Skip to content

Commit

Permalink
feat(crypto): add blst (#20296)
Browse files Browse the repository at this point in the history
Co-authored-by: itsdevbear <[email protected]>
Co-authored-by: Akhil Kumar P <[email protected]>
  • Loading branch information
3 people authored Jun 11, 2024
1 parent 78327f4 commit 05ff7a7
Show file tree
Hide file tree
Showing 20 changed files with 932 additions and 32 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ ifeq (boltdb,$(findstring boltdb,$(COSMOS_BUILD_OPTIONS)))
build_tags += boltdb
endif

# handle blst
ifeq (blst,$(findstring blst,$(COSMOS_BUILD_OPTIONS)))
CGO_ENABLED=1
build_tags += blst
endif

whitespace :=
whitespace += $(whitespace)
comma := ,
Expand Down
4 changes: 3 additions & 1 deletion crypto/codec/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"github.com/cometbft/cometbft/crypto/sr25519"

"cosmossdk.io/core/legacy"

bls12_381 "github.com/cosmos/cosmos-sdk/crypto/keys/bls12_381"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
Expand All @@ -21,6 +21,7 @@ func RegisterCrypto(cdc legacy.Amino) {
ed25519.PubKeyName)
cdc.RegisterConcrete(&secp256k1.PubKey{},
secp256k1.PubKeyName)
cdc.RegisterConcrete(&bls12_381.PubKey{}, bls12_381.PubKeyName)
cdc.RegisterConcrete(&kmultisig.LegacyAminoPubKey{},
kmultisig.PubKeyAminoRoute)

Expand All @@ -31,4 +32,5 @@ func RegisterCrypto(cdc legacy.Amino) {
ed25519.PrivKeyName)
cdc.RegisterConcrete(&secp256k1.PrivKey{},
secp256k1.PrivKeyName)
cdc.RegisterConcrete(&bls12_381.PrivKey{}, bls12_381.PrivKeyName)
}
12 changes: 11 additions & 1 deletion crypto/codec/cmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/cometbft/cometbft/crypto/encoding"

"cosmossdk.io/errors"

bls12_381 "github.com/cosmos/cosmos-sdk/crypto/keys/bls12_381"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
Expand All @@ -24,6 +24,10 @@ func FromCmtProtoPublicKey(protoPk cmtprotocrypto.PublicKey) (cryptotypes.PubKey
return &secp256k1.PubKey{
Key: protoPk.Secp256K1,
}, nil
case *cmtprotocrypto.PublicKey_Bls12381:
return &bls12_381.PubKey{
Key: protoPk.Bls12381,
}, nil
default:
return nil, errors.Wrapf(sdkerrors.ErrInvalidType, "cannot convert %v from Tendermint public key", protoPk)
}
Expand All @@ -44,6 +48,12 @@ func ToCmtProtoPublicKey(pk cryptotypes.PubKey) (cmtprotocrypto.PublicKey, error
Secp256K1: pk.Key,
},
}, nil
case *bls12_381.PubKey:
return cmtprotocrypto.PublicKey{
Sum: &cmtprotocrypto.PublicKey_Bls12381{
Bls12381: pk.Key,
},
}, nil
default:
return cmtprotocrypto.PublicKey{}, errors.Wrapf(sdkerrors.ErrInvalidType, "cannot convert %v to Tendermint public key", pk)
}
Expand Down
3 changes: 3 additions & 0 deletions crypto/codec/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package codec
import (
"cosmossdk.io/core/registry"

bls12_381 "github.com/cosmos/cosmos-sdk/crypto/keys/bls12_381"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
Expand All @@ -16,11 +17,13 @@ func RegisterInterfaces(registry registry.InterfaceRegistrar) {
registry.RegisterInterface("cosmos.crypto.PubKey", pk)
registry.RegisterImplementations(pk, &ed25519.PubKey{})
registry.RegisterImplementations(pk, &secp256k1.PubKey{})
registry.RegisterImplementations(pk, &bls12_381.PubKey{})
registry.RegisterImplementations(pk, &multisig.LegacyAminoPubKey{})

var priv *cryptotypes.PrivKey
registry.RegisterInterface("cosmos.crypto.PrivKey", priv)
registry.RegisterImplementations(priv, &secp256k1.PrivKey{})
registry.RegisterImplementations(priv, &ed25519.PrivKey{})
registry.RegisterImplementations(priv, &bls12_381.PrivKey{})
secp256r1.RegisterInterfaces(registry)
}
3 changes: 3 additions & 0 deletions crypto/hd/algo.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const (
// Ed25519Type represents the Ed25519Type signature system.
// It is currently not supported for end-user keys (wallets/ledgers).
Ed25519Type = PubKeyType("ed25519")
// Ed25519Type represents the Ed25519Type signature system.
// It is currently not supported for end-user keys (wallets/ledgers).
Bls12_381Type = PubKeyType("bls12_381")
// Sr25519Type represents the Sr25519Type signature system.
Sr25519Type = PubKeyType("sr25519")
)
Expand Down
20 changes: 20 additions & 0 deletions crypto/keys/bls12_381/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package bls12_381

const (
PrivKeyName = "cometbft/PrivKeyBls12_381"
PubKeyName = "cometbft/PubKeyBls12_381"
// PubKeySize is the size, in bytes, of public keys as used in this package.
PubKeySize = 32
// PrivKeySize is the size, in bytes, of private keys as used in this package.
PrivKeySize = 64
// SignatureLength defines the byte length of a BLS signature.
SignatureLength = 96
// SeedSize is the size, in bytes, of private key seeds. These are the
// private key representations used by RFC 8032.
SeedSize = 32

// MaxMsgLen defines the maximum length of the message bytes as passed to Sign.
MaxMsgLen = 32

KeyType = "bls12381"
)
131 changes: 131 additions & 0 deletions crypto/keys/bls12_381/key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package bls12_381

import (
"bytes"
"errors"
"fmt"

"github.com/cometbft/cometbft/crypto"

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

// ===============================================================================================
// Private Key
// ===============================================================================================

// PrivKey is a wrapper around the Ethereum BLS12-381 private key type. This
// wrapper conforms to crypto.Pubkey to allow for the use of the Ethereum
// BLS12-381 private key type.

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

// NewPrivateKeyFromBytes build a new key from the given bytes.
func NewPrivateKeyFromBytes(bz []byte) (PrivKey, error) {
panic("not implemented, build flags are required to use bls12_381 keys")
}

// GenPrivKey generates a new key.
func GenPrivKey() (PrivKey, error) {
panic("not implemented, build flags are required to use bls12_381 keys")
}

// Bytes returns the byte representation of the Key.
func (privKey PrivKey) Bytes() []byte {
panic("not implemented, build flags are required to use bls12_381 keys")
}

// PubKey returns the private key's public key. If the privkey is not valid
// it returns a nil value.
func (privKey PrivKey) PubKey() cryptotypes.PubKey {
panic("not implemented, build flags are required to use bls12_381 keys")
}

// Equals returns true if two keys are equal and false otherwise.
func (privKey PrivKey) Equals(other cryptotypes.LedgerPrivKey) bool {
panic("not implemented, build flags are required to use bls12_381 keys")
}

// Type returns the type.
func (PrivKey) Type() string {
return KeyType
}

// Sign signs the given byte array. If msg is larger than
// MaxMsgLen, SHA256 sum will be signed instead of the raw bytes.
func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
panic("not implemented, build flags are required to use bls12_381 keys")
}

// MarshalAmino overrides Amino binary marshaling.
func (privKey PrivKey) MarshalAmino() ([]byte, error) {
return privKey.Key, nil
}

// UnmarshalAmino overrides Amino binary marshaling.
func (privKey *PrivKey) UnmarshalAmino(bz []byte) error {
if len(bz) != PrivKeySize {
return errors.New("invalid privkey size")
}
privKey.Key = bz

return nil
}

// MarshalAminoJSON overrides Amino JSON marshaling.
func (privKey PrivKey) MarshalAminoJSON() ([]byte, error) {
// When we marshal to Amino JSON, we don't marshal the "key" field itself,
// just its contents (i.e. the key bytes).
return privKey.MarshalAmino()
}

// UnmarshalAminoJSON overrides Amino JSON marshaling.
func (privKey *PrivKey) UnmarshalAminoJSON(bz []byte) error {
return privKey.UnmarshalAmino(bz)
}

// ===============================================================================================
// Public Key
// ===============================================================================================

// Pubkey is a wrapper around the Ethereum BLS12-381 public key type. This
// wrapper conforms to crypto.Pubkey to allow for the use of the Ethereum
// BLS12-381 public key type.

var _ cryptotypes.PubKey = &PubKey{}

// Address returns the address of the key.
//
// The function will panic if the public key is invalid.
func (pubKey PubKey) Address() crypto.Address {
panic("not implemented, build flags are required to use bls12_381 keys")
}

// VerifySignature verifies the given signature.
func (pubKey PubKey) VerifySignature(msg, sig []byte) bool {
panic("not implemented, build flags are required to use bls12_381 keys")
}

// Bytes returns the byte format.
func (pubKey PubKey) Bytes() []byte {
return pubKey.Key
}

// Type returns the key's type.
func (PubKey) Type() string {
return KeyType
}

// Equals returns true if the other's type is the same and their bytes are deeply equal.
func (pubKey PubKey) Equals(other cryptotypes.PubKey) bool {
return pubKey.Type() == other.Type() && bytes.Equal(pubKey.Bytes(), other.Bytes())
}

// String returns Hex representation of a pubkey with it's type
func (pubKey PubKey) String() string {
return fmt.Sprintf("PubKeyBLS12_381{%X}", pubKey.Key)
}
Loading

0 comments on commit 05ff7a7

Please sign in to comment.