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

threshold bn254 key support #236

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
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
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ linters-settings:
alias: boltdb
- pkg: math/rand
alias: mrand
- pkg: github.com/consensys/gnark-crypto/ecc/bn254/ecdsa
alias: ecdsa_bn254
- pkg: github.com/strangelove-ventures/horcrux/v3/signer/bn254
alias: horcrux_bn254
maligned:
suggest-new: true
govet:
Expand Down
14 changes: 7 additions & 7 deletions cmd/horcrux/cmd/address.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package cmd

import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"strings"

"github.com/cometbft/cometbft/crypto"
cometprivval "github.com/cometbft/cometbft/privval"
"github.com/cosmos/cosmos-sdk/types/bech32"
"github.com/spf13/cobra"
Expand All @@ -29,7 +29,7 @@ func addressCmd() *cobra.Command {
Args: cobra.RangeArgs(1, 2),
RunE: func(cmd *cobra.Command, args []string) error {

var pubKey crypto.PubKey
var pubKey []byte

chainID := args[0]

Expand All @@ -45,7 +45,7 @@ func addressCmd() *cobra.Command {
return err
}

key, err := signer.LoadCosignerEd25519Key(keyFile)
key, err := signer.LoadCosignerKey(keyFile)
if err != nil {
return fmt.Errorf("error reading cosigner key: %w, check that key is present for chain ID: %s", err, chainID)
}
Expand All @@ -62,25 +62,25 @@ func addressCmd() *cobra.Command {
}

filePV := cometprivval.LoadFilePVEmptyState(keyFile, "")
pubKey = filePV.Key.PubKey
pubKey = filePV.Key.PubKey.Bytes()
default:
panic(fmt.Errorf("unexpected sign mode: %s", config.Config.SignMode))
}

pubKeyAddress := pubKey.Address()
address := sha256.New().Sum(pubKey)[:20]

pubKeyJSON, err := signer.PubKey("", pubKey)
if err != nil {
return err
}

output := AddressCmdOutput{
HexAddress: strings.ToUpper(hex.EncodeToString(pubKeyAddress)),
HexAddress: strings.ToUpper(hex.EncodeToString(address)),
PubKey: pubKeyJSON,
}

if len(args) == 2 {
bech32ValConsAddress, err := bech32.ConvertAndEncode(args[1]+"valcons", pubKeyAddress)
bech32ValConsAddress, err := bech32.ConvertAndEncode(args[1]+"valcons", address)
if err != nil {
return err
}
Expand Down
21 changes: 11 additions & 10 deletions cmd/horcrux/cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import (

cometcrypto "github.com/cometbft/cometbft/crypto"
cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519"
cometcryptoencoding "github.com/cometbft/cometbft/crypto/encoding"
cometprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto"
"github.com/spf13/cobra"
"github.com/strangelove-ventures/horcrux/v3/signer"
"github.com/strangelove-ventures/horcrux/v3/signer/encoding"
"github.com/strangelove-ventures/horcrux/v3/signer/proto"
amino "github.com/tendermint/go-amino"
"gopkg.in/yaml.v2"
)
Expand Down Expand Up @@ -98,12 +98,12 @@ func (key *v2CosignerKey) UnmarshalJSON(data []byte) error {
}

var pubkey cometcrypto.PubKey
var protoPubkey cometprotocrypto.PublicKey
var protoPubkey proto.PublicKey
err = protoPubkey.Unmarshal(aux.PubkeyBytes)

// Prior to the tendermint protobuf migration, the public key bytes in key files
// were encoded using the go-amino libraries via
// cdc.MarshalBinaryBare(CosignerEd25519Key.PubKey)
// cdc.MarshalBinaryBare(CosignerKey.PubKey)
//
// To support reading the public key bytes from these key files, we fallback to
// amino unmarshalling if the protobuf unmarshalling fails
Expand All @@ -118,7 +118,7 @@ func (key *v2CosignerKey) UnmarshalJSON(data []byte) error {
}
pubkey = pub
} else {
pubkey, err = cometcryptoencoding.PubKeyFromProto(protoPubkey)
pubkey, err = encoding.PubKeyFromProto(protoPubkey)
if err != nil {
return err
}
Expand Down Expand Up @@ -218,13 +218,14 @@ func migrateCmd() *cobra.Command {
return err
}

newEd25519Key := signer.CosignerEd25519Key{
PubKey: legacyCosignerKey.PubKey,
newEd25519Key := &signer.CosignerKey{
KeyType: signer.CosignerKeyTypeEd25519,
PubKey: legacyCosignerKey.PubKey.Bytes(),
PrivateShard: legacyCosignerKey.ShareKey,
ID: legacyCosignerKey.ID,
}

newEd25519KeyBz, err := newEd25519Key.MarshalJSON()
newEd25519KeyBz, err := json.Marshal(newEd25519Key)
if err != nil {
return fmt.Errorf("failed to marshal new Ed25519 key to json: %w", err)
}
Expand All @@ -234,13 +235,13 @@ func migrateCmd() *cobra.Command {
return fmt.Errorf("failed to write new Ed25519 key to %s: %w", newEd25519Path, err)
}

newRSAKey := signer.CosignerRSAKey{
newRSAKey := &signer.CosignerRSAKey{
RSAKey: legacyCosignerKey.RSAKey,
ID: legacyCosignerKey.ID,
RSAPubs: legacyCosignerKey.RSAPubs,
}

newRSAKeyBz, err := newRSAKey.MarshalJSON()
newRSAKeyBz, err := json.Marshal(newRSAKey)
if err != nil {
return fmt.Errorf("failed to marshal new RSA key to json: %w", err)
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/horcrux/cmd/migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestMigrateV2toV3(t *testing.T) {
newKeyShardFileBz, err := os.ReadFile(newKeyShardFile)
require.NoError(t, err)

require.Equal(t, testdata.CosignerEd25519KeyMigrated, string(newKeyShardFileBz))
require.Equal(t, testdata.CosignerKeyMigrated, string(newKeyShardFileBz))

newRSAKeyFileBz, err := os.ReadFile(newRSAKeyFile)
require.NoError(t, err)
Expand Down Expand Up @@ -104,7 +104,7 @@ func TestMigrateV2toV3DifferentKeyFilePath(t *testing.T) {
newKeyShardFileBz, err := os.ReadFile(newKeyShardFile)
require.NoError(t, err)

require.Equal(t, testdata.CosignerEd25519KeyMigrated, string(newKeyShardFileBz))
require.Equal(t, testdata.CosignerKeyMigrated, string(newKeyShardFileBz))

newRSAKeyFileBz, err := os.ReadFile(newRSAKeyFile)
require.NoError(t, err)
Expand Down Expand Up @@ -144,7 +144,7 @@ func TestMigrateV2toV3KeysOnly(t *testing.T) {
newKeyShardFileBz, err := os.ReadFile(newKeyShardFile)
require.NoError(t, err)

require.Equal(t, testdata.CosignerEd25519KeyMigrated, string(newKeyShardFileBz))
require.Equal(t, testdata.CosignerKeyMigrated, string(newKeyShardFileBz))

newRSAKeyFileBz, err := os.ReadFile(newRSAKeyFile)
require.NoError(t, err)
Expand Down Expand Up @@ -184,7 +184,7 @@ func TestMigrateV2toV3ConfigAlreadyMigrated(t *testing.T) {
newKeyShardFileBz, err := os.ReadFile(newKeyShardFile)
require.NoError(t, err)

require.Equal(t, testdata.CosignerEd25519KeyMigrated, string(newKeyShardFileBz))
require.Equal(t, testdata.CosignerKeyMigrated, string(newKeyShardFileBz))

newRSAKeyFileBz, err := os.ReadFile(newRSAKeyFile)
require.NoError(t, err)
Expand All @@ -208,7 +208,7 @@ func TestMigrateV2toV3AlreadyMigrated(t *testing.T) {

ed25519KeyShardFile := filepath.Join(tmp, "test_shard.json")

err = os.WriteFile(ed25519KeyShardFile, []byte(testdata.CosignerEd25519KeyMigrated), 0600)
err = os.WriteFile(ed25519KeyShardFile, []byte(testdata.CosignerKeyMigrated), 0600)
require.NoError(t, err)

rsaKeyShardFile := filepath.Join(tmp, "rsa_keys.json")
Expand Down
2 changes: 1 addition & 1 deletion cmd/horcrux/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func rootCmd() *cobra.Command {
cmd.AddCommand(configCmd())
cmd.AddCommand(startCmd())
cmd.AddCommand(addressCmd())
cmd.AddCommand(createCosignerEd25519ShardsCmd())
cmd.AddCommand(createCosignerShardsCmd())
cmd.AddCommand(createCosignerECIESShardsCmd())

rsaCmd := createCosignerRSAShardsCmd()
Expand Down
15 changes: 8 additions & 7 deletions cmd/horcrux/cmd/shards.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ func addTotalShardsFlag(cmd *cobra.Command) {

// createCosignerEd25519ShardsCmd is a cobra command for creating
// cosigner shards from a full priv validator key.
func createCosignerEd25519ShardsCmd() *cobra.Command {
func createCosignerShardsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create-ed25519-shards",
Args: cobra.NoArgs,
Short: "Create cosigner Ed25519 shards",
Use: "create-shards",
Aliases: []string{"create-ed25519-shards", "create-bn254-shards"},
Args: cobra.NoArgs,
Short: "Create cosigner consensus key shards",
RunE: func(cmd *cobra.Command, args []string) (err error) {
flags := cmd.Flags()

Expand Down Expand Up @@ -112,7 +113,7 @@ func createCosignerEd25519ShardsCmd() *cobra.Command {
return nil
}

csKeys, err := signer.CreateCosignerEd25519ShardsFromFile(keyFile, threshold, shards)
csKeys, err := signer.CreateCosignerShardsFromFile(keyFile, threshold, shards)
if err != nil {
return err
}
Expand All @@ -133,10 +134,10 @@ func createCosignerEd25519ShardsCmd() *cobra.Command {
return err
}
filename := filepath.Join(dir, fmt.Sprintf("%s_shard.json", chainID))
if err = signer.WriteCosignerEd25519ShardFile(c, filename); err != nil {
if err = signer.WriteCosignerShardFile(c, filename); err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "Created Ed25519 Shard %s\n", filename)
fmt.Fprintf(cmd.OutOrStdout(), "Created %s Shard %s\n", c.KeyType, filename)
}
return nil
},
Expand Down
58 changes: 58 additions & 0 deletions cmd/horcrux/cmd/shards_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import (
"testing"

"github.com/cometbft/cometbft/crypto/ed25519"
cometjson "github.com/cometbft/cometbft/libs/json"
"github.com/cometbft/cometbft/privval"
"github.com/strangelove-ventures/horcrux/cmd/horcrux/cmd/testdata"
"github.com/strangelove-ventures/horcrux/v3/signer"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -139,3 +142,58 @@ func TestRSAShards(t *testing.T) {
})
}
}

func TestPrivValidatorBn254(t *testing.T) {
bz := testdata.PrivValidatorKeyBn254
var privvalKey privval.FilePVKey
err := cometjson.Unmarshal(bz, &privvalKey)
require.NoError(t, err)

msg := []byte("hello")

sig, err := privvalKey.PrivKey.Sign(msg)
require.NoError(t, err)

valid := privvalKey.PrivKey.PubKey().VerifySignature(msg, sig)
require.True(t, valid)

valid = privvalKey.PubKey.VerifySignature(msg, sig)
require.True(t, valid)

shards, err := signer.CreateCosignerShards(&privvalKey, 2, 3)
require.NoError(t, err)

var signers = make([]*signer.ThresholdSignerSoftBn254, len(shards))
var sigs = make([][]byte, len(shards))

for i, shard := range shards {
shard := shard
signers[i], err = signer.NewThresholdSignerSoftBn254(&shard, 2, 3)
require.NoError(t, err)

sig, err = signers[i].Sign(nil, msg)
require.NoError(t, err)

sigs[i] = sig
}

var partialSigs = make([]signer.PartialSignature, 0, 2)
for i, sig := range sigs {
if i == 0 {
continue
}
partialSigs = append(partialSigs, signer.PartialSignature{
ID: i + 1,
Signature: sig,
})
}

combinedSig, err := signers[0].CombineSignatures(partialSigs)
require.NoError(t, err)

valid = privvalKey.PrivKey.PubKey().VerifySignature(msg, combinedSig)
require.True(t, valid)

valid = privvalKey.PubKey.VerifySignature(msg, combinedSig)
require.True(t, valid)
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"pubKey":"CiBRLhKCqDU6Wufhj0TZK6jNO8LreArc+CKHKYitdTyYUg==","privateShard":"q0zuUQpplAfBJxoA2e2O1H7BdBgopzhPmL8mIWP8AQw=","id":3}
{"pubKey":"CiBRLhKCqDU6Wufhj0TZK6jNO8LreArc+CKHKYitdTyYUg==","keyType":"ed25519","privateShard":"q0zuUQpplAfBJxoA2e2O1H7BdBgopzhPmL8mIWP8AQw=","id":3}
11 changes: 11 additions & 0 deletions cmd/horcrux/cmd/testdata/priv_validator_key-bn254.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"address": "092F3E64DF1B43207DCB187747C7E35A0A8C277B",
"pub_key": {
"type": "tendermint/PubKeyBn254",
"value": "jX4uANsjStZrWdWurqaFKXB8AQjoUhd/GiZjeEAB01Y="
},
"priv_key": {
"type": "tendermint/PrivKeyBn254",
"value": "0sZKL1ORco5/VXVtoLSaF2QS4TmzZlBgctr1aUfja1gCXu6OqvPob9f2q7XnzSQRCL1gmY1SsYcoImN4iR/HSg=="
}
}
5 changes: 4 additions & 1 deletion cmd/horcrux/cmd/testdata/testdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ var ConfigMigrated string
var ConfigV2 []byte

//go:embed cosigner-key-migrated-ed25519.json
var CosignerEd25519KeyMigrated string
var CosignerKeyMigrated string

//go:embed cosigner-key-migrated-rsa.json
var CosignerRSAKeyMigrated string

//go:embed cosigner-key-v2.json
var CosignerKeyV2 []byte

//go:embed priv_validator_key-bn254.json
var PrivValidatorKeyBn254 []byte
Loading
Loading