Skip to content

Commit

Permalink
feat: implement bls key generation (#86)
Browse files Browse the repository at this point in the history
  • Loading branch information
gitferry authored Aug 9, 2022
1 parent 409fe75 commit e09cd50
Show file tree
Hide file tree
Showing 10 changed files with 424 additions and 38 deletions.
41 changes: 27 additions & 14 deletions cmd/babylond/cmd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import (
"bufio"
"encoding/json"
"fmt"
"github.com/babylonchain/babylon/privval"
"github.com/babylonchain/babylon/testutil/datagen"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"net"
"os"
"path/filepath"
Expand Down Expand Up @@ -120,7 +123,8 @@ func InitTestnet(
}

nodeIDs := make([]string, numValidators)
valPubKeys := make([]cryptotypes.PubKey, numValidators)
valPubkeys := make([]cryptotypes.PubKey, numValidators)
valKeys := make([]*privval.ValidatorKeys, numValidators)

babylonConfig := srvconfig.DefaultConfig()
babylonConfig.MinGasPrices = minGasPrices
Expand Down Expand Up @@ -159,31 +163,35 @@ func InitTestnet(
return err
}

nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}

memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
genFiles = append(genFiles, nodeConfig.GenesisFile())

// generate account key
kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, nodeDir, inBuf)
if err != nil {
return err
}

keyringAlgos, _ := kb.SupportedAlgorithms()
algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos)
if err != nil {
return err
}

addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, "", true, algo)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}
accKeyInfo, err := kb.Key(nodeDirName)
if err != nil {
return err
}

// generate validator keys
nodeIDs[i], valKeys[i], err = datagen.InitializeNodeValidatorFiles(nodeConfig, accKeyInfo.GetPubKey())
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}

memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
genFiles = append(genFiles, nodeConfig.GenesisFile())

info := map[string]string{"secret": secret}

Expand All @@ -208,9 +216,14 @@ func InitTestnet(
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))

valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction)
valPubkey, err := cryptocodec.FromTmPubKeyInterface(valKeys[i].ValPubkey)
if err != nil {
return err
}
valPubkeys = append(valPubkeys, valPubkey)
createValMsg, err := stakingtypes.NewMsgCreateValidator(
sdk.ValAddress(addr),
valPubKeys[i],
valPubkey,
sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()),
Expand Down Expand Up @@ -255,7 +268,7 @@ func InitTestnet(
}

err := collectGenFiles(
clientCtx, nodeConfig, chainID, nodeIDs, valPubKeys, numValidators,
clientCtx, nodeConfig, chainID, nodeIDs, valPubkeys, numValidators,
outputDir, nodeDirPrefix, nodeDaemonHome, genBalIterator,
)
if err != nil {
Expand Down
42 changes: 37 additions & 5 deletions crypto/bls12381/bls.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,54 @@
package bls12381

import (
"crypto/rand"
"github.com/pkg/errors"
blst "github.com/supranational/blst/bindings/go"
tmcrypto "github.com/tendermint/tendermint/crypto"
"io"
)

// GenKeyPair generates a random BLS key pair based on a given seed
// the public key is compressed with 96 byte size
func GenKeyPair(seed []byte) (*blst.SecretKey, PublicKey) {
sk := blst.KeyGen(seed)
func GenKeyPair() (PrivateKey, PublicKey) {
skSerialized := GenPrivKey()
sk := new(blst.SecretKey)
sk.Deserialize(skSerialized)
pk := new(BlsPubKey).From(sk)
return sk, pk.Compress()
return skSerialized, pk.Compress()
}

func GenPrivKey() PrivateKey {
return genPrivKey(rand.Reader)
}

func GenPrivKeyFromSecret(secret []byte) PrivateKey {
seed := tmcrypto.Sha256(secret)

return genPrivKeyFromSeed(seed)
}

func genPrivKey(rand io.Reader) PrivateKey {
seed := make([]byte, SeedSize)

_, err := io.ReadFull(rand, seed)
if err != nil {
panic(err)
}

return genPrivKeyFromSeed(seed)
}

func genPrivKeyFromSeed(seed []byte) PrivateKey {
return blst.KeyGen(seed).Serialize()
}

// Sign signs on a msg using a BLS secret key
// the returned sig is compressed version with 48 byte size
func Sign(sk *blst.SecretKey, msg []byte) Signature {
return new(BlsSig).Sign(sk, msg, DST).Compress()
func Sign(sk PrivateKey, msg []byte) Signature {
secretKey := new(blst.SecretKey)
secretKey.Deserialize(sk)
return new(BlsSig).Sign(secretKey, msg, DST).Compress()
}

// Verify verifies a BLS sig over msg with a BLS public key
Expand Down
22 changes: 11 additions & 11 deletions crypto/bls12381/bls_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package bls12381

import (
"crypto/rand"
"github.com/stretchr/testify/require"
"testing"

blst "github.com/supranational/blst/bindings/go"
)

// Tests single BLS sig verification
func TestVerifyBlsSig(t *testing.T) {
msga := []byte("aaaaaaaa")
msgb := []byte("bbbbbbbb")
sk, pk := genRandomKeyPair()
sk, pk := GenKeyPair()
sig := Sign(sk, msga)
// a byte size of a sig (compressed) is 48
require.Equal(t, 48, len(sig))
Expand Down Expand Up @@ -95,17 +92,20 @@ func TestAccumulativeAggregation(t *testing.T) {
require.Nil(t, err)
}

func genRandomKeyPair() (*blst.SecretKey, PublicKey) {
var ikm [32]byte
_, _ = rand.Read(ikm[:])
return GenKeyPair(ikm[:])
func TestSKToPK(t *testing.T) {
n := 100
sks, pks := generateBatchTestKeyPairs(n)
for i := 0; i < n; i++ {
ok := sks[i].PubKey().Equal(pks[i])
require.True(t, ok)
}
}

func generateBatchTestKeyPairs(n int) ([]*blst.SecretKey, []PublicKey) {
sks := make([]*blst.SecretKey, n)
func generateBatchTestKeyPairs(n int) ([]PrivateKey, []PublicKey) {
sks := make([]PrivateKey, n)
pubks := make([]PublicKey, n)
for i := 0; i < n; i++ {
sk, pk := genRandomKeyPair()
sk, pk := GenKeyPair()
sks[i] = sk
pubks[i] = pk
}
Expand Down
26 changes: 20 additions & 6 deletions crypto/bls12381/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,22 @@ var DST = []byte("BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_")

type Signature []byte
type PublicKey []byte

const SignatureLen = 48
const PublicKeyLen = 96
type PrivateKey []byte

const (
// SignatureSize is the size, in bytes, of a compressed BLS signature
SignatureSize = 48
// PubKeySize is the size, in bytes, of a compressed BLS public key
PubKeySize = 96
// SeedSize is the size, in bytes, of private key seeds
SeedSize = 32
)

func (sig Signature) ValidateBasic() error {
if sig == nil {
return errors.New("invalid BLS signature")
}
if len(sig) != SignatureLen {
if len(sig) != SignatureSize {
return errors.New("invalid BLS signature")
}

Expand Down Expand Up @@ -65,7 +72,7 @@ func (sig Signature) Size() int {
}

func (sig *Signature) Unmarshal(data []byte) error {
if len(data) != SignatureLen {
if len(data) != SignatureSize {
return errors.New("Invalid signature length")
}

Expand Down Expand Up @@ -126,7 +133,7 @@ func (pk PublicKey) Size() int {
}

func (pk *PublicKey) Unmarshal(data []byte) error {
if len(data) != PublicKeyLen {
if len(data) != PubKeySize {
return errors.New("Invalid public key length")
}

Expand All @@ -141,3 +148,10 @@ func (pk PublicKey) Equal(k PublicKey) bool {
func (pk PublicKey) Byte() []byte {
return pk
}

func (sk PrivateKey) PubKey() PublicKey {
secretKey := new(blst.SecretKey)
secretKey.Deserialize(sk)
pk := new(BlsPubKey).From(secretKey)
return pk.Compress()
}
Loading

0 comments on commit e09cd50

Please sign in to comment.