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: extend the maximum number of characters that can be decoded to 200 characters #159

Merged
merged 5 commits into from
Jan 25, 2021
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
37 changes: 28 additions & 9 deletions crypto/composite/composite.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,38 @@
package composite

import (
"bytes"

"github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/bls"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
)

// PubKeyComposite and PrivKeyComposite are intended to allow public key algorithms to be selected for each function.

const (
PubKeyCompositeAminoName = "tendermint/PubKeyComposite"
PrivKeyCompositeAminoName = "tendermint/PrivKeyComposite"
PrivKeyAminoName = "tendermint/PrivKeyComposite"
PubKeyAminoName = "tendermint/PubKeyComposite"
)

var cdc = amino.NewCodec()

func init() {
cdc.RegisterInterface((*crypto.PubKey)(nil), nil)
cdc.RegisterConcrete(PubKeyComposite{},
PubKeyAminoName, nil)
cdc.RegisterConcrete(bls.PubKeyBLS12{},
bls.PubKeyAminoName, nil)
cdc.RegisterConcrete(ed25519.PubKeyEd25519{},
ed25519.PubKeyAminoName, nil)
cdc.RegisterInterface((*crypto.PrivKey)(nil), nil)
cdc.RegisterConcrete(PrivKeyComposite{},
PrivKeyAminoName, nil)
cdc.RegisterConcrete(bls.PrivKeyBLS12{},
bls.PrivKeyAminoName, nil)
cdc.RegisterConcrete(ed25519.PrivKeyEd25519{},
ed25519.PrivKeyAminoName, nil)
}

type PubKeyComposite struct {
SignKey crypto.PubKey `json:"sign"`
VrfKey crypto.PubKey `json:"vrf"`
Expand All @@ -30,9 +47,11 @@ func (pk PubKeyComposite) Address() crypto.Address {
}

func (pk PubKeyComposite) Bytes() []byte {
msg := bytes.NewBuffer(pk.SignKey.Bytes())
msg.Write(pk.VrfKey.Bytes())
return msg.Bytes()
bz, err := cdc.MarshalBinaryBare(pk)
Copy link
Member

Choose a reason for hiding this comment

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

Why are we using bytes.NewBuffer?

Copy link
Member

Choose a reason for hiding this comment

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

FYI: https://github.com/line/tendermint/blob/develop/docs/architecture/adr-015-crypto-encoding.md

Context

We must standardize our method for encoding public keys and signatures on chain. Currently we amino encode the public keys and signatures. The reason we are using amino here is primarily due to ease of support in parsing for other languages. We don't need its upgradability properties in cryptosystems, as a change in the crypto that requires adapting the encoding, likely warrants being deemed a new cryptosystem. (I.e. using new public parameters)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you. It was used to identify it as a unique value as a [] byte array inside tendermint. However, according to the specifications of tendermint, it seems correct to use amino encoding.

if err != nil {
panic(err)
}
return bz
}

func (pk PubKeyComposite) VerifyBytes(msg []byte, sig []byte) bool {
Expand Down Expand Up @@ -67,7 +86,7 @@ func (sk PrivKeyComposite) Identity() crypto.PrivKey {
}

func (sk PrivKeyComposite) Bytes() []byte {
return sk.Identity().Bytes()
return cdc.MustMarshalBinaryBare(sk)
Copy link
Member

Choose a reason for hiding this comment

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

Why are we using sk.Identity().Bytes()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As I answered above, the reason is the same as PubKeyComposite.

}

func (sk PrivKeyComposite) Sign(msg []byte) ([]byte, error) {
Expand Down
6 changes: 3 additions & 3 deletions crypto/composite/composite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ func TestEnvironmentalCompatibility(t *testing.T) {
cdc.RegisterConcrete(bls.PrivKeyBLS12{}, bls.PrivKeyAminoName, nil)
cdc.RegisterConcrete(ed25519.PubKeyEd25519{}, ed25519.PubKeyAminoName, nil)
cdc.RegisterConcrete(ed25519.PrivKeyEd25519{}, ed25519.PrivKeyAminoName, nil)
cdc.RegisterConcrete(composite.PubKeyComposite{}, composite.PubKeyCompositeAminoName, nil)
cdc.RegisterConcrete(composite.PrivKeyComposite{}, composite.PrivKeyCompositeAminoName, nil)
cdc.RegisterConcrete(composite.PubKeyComposite{}, composite.PubKeyAminoName, nil)
cdc.RegisterConcrete(composite.PrivKeyComposite{}, composite.PrivKeyAminoName, nil)

t.Run("MarshalCompositeKey", func(t *testing.T) {
privKey := composite.GenPrivKey()
Expand Down Expand Up @@ -253,7 +253,7 @@ func TestEnvironmentalCompatibility(t *testing.T) {
// compare addresses to assumed value
compositePrivKey := composite.NewPrivKeyComposite(blsPrivKey, ed25519PrivKey)
compositePubKey := compositePrivKey.PubKey()
address, err := hex.DecodeString("7A68265205CB115AE35A13515C423F1721E87BB4")
address, err := hex.DecodeString("72dd758835404175940f698cf3ddc29dd0d04afa")
if err != nil {
t.Fatal(err)
}
Expand Down
6 changes: 3 additions & 3 deletions crypto/encoding/amino/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func init() {
nameTable[reflect.TypeOf(sr25519.PubKeySr25519{})] = sr25519.PubKeyAminoName
nameTable[reflect.TypeOf(secp256k1.PubKeySecp256k1{})] = secp256k1.PubKeyAminoName
nameTable[reflect.TypeOf(multisig.PubKeyMultisigThreshold{})] = multisig.PubKeyMultisigThresholdAminoRoute
nameTable[reflect.TypeOf(composite.PubKeyComposite{})] = composite.PubKeyCompositeAminoName
nameTable[reflect.TypeOf(composite.PubKeyComposite{})] = composite.PubKeyAminoName
}

// PubkeyAminoName returns the amino route of a pubkey
Expand All @@ -64,7 +64,7 @@ func RegisterAmino(cdc *amino.Codec) {
cdc.RegisterConcrete(multisig.PubKeyMultisigThreshold{},
multisig.PubKeyMultisigThresholdAminoRoute, nil)
cdc.RegisterConcrete(composite.PubKeyComposite{},
composite.PubKeyCompositeAminoName, nil)
composite.PubKeyAminoName, nil)

cdc.RegisterInterface((*crypto.PrivKey)(nil), nil)
cdc.RegisterConcrete(bls.PrivKeyBLS12{},
Expand All @@ -76,7 +76,7 @@ func RegisterAmino(cdc *amino.Codec) {
cdc.RegisterConcrete(secp256k1.PrivKeySecp256k1{},
secp256k1.PrivKeyAminoName, nil)
cdc.RegisterConcrete(composite.PrivKeyComposite{},
composite.PrivKeyCompositeAminoName, nil)
composite.PrivKeyAminoName, nil)
}

// RegisterKeyType registers an external key type to allow decoding it from bytes
Expand Down
20 changes: 18 additions & 2 deletions crypto/encoding/amino/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import (
"reflect"
"testing"

"github.com/tendermint/tendermint/crypto/bls"

"github.com/tendermint/tendermint/crypto/composite"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand All @@ -31,7 +35,6 @@ func checkAminoBinary(t *testing.T, src, dst interface{}, size int) {
}
// Make sure we have the expected length.
assert.Equal(t, size, len(bz), "Amino binary size mismatch")

// Unmarshal.
err = cdc.UnmarshalBinaryBare(bz, dst)
require.Nil(t, err, "%+v", err)
Expand Down Expand Up @@ -94,10 +97,21 @@ func TestKeyEncodings(t *testing.T) {
pubSize: 38,
sigSize: 65,
},
{
privKey: bls.GenPrivKey(),
privSize: 37,
pubSize: 53,
sigSize: 97,
},
{
privKey: *composite.GenPrivKey(),
privSize: 114,
pubSize: 98,
sigSize: 97,
},
}

for tcIndex, tc := range cases {

// Check (de/en)codings of PrivKeys.
var priv2, priv3 crypto.PrivKey
checkAminoBinary(t, tc.privKey, &priv2, tc.privSize)
Expand Down Expand Up @@ -155,6 +169,8 @@ func TestPubkeyAminoName(t *testing.T) {
{ed25519.PubKeyEd25519{}, ed25519.PubKeyAminoName, true},
{sr25519.PubKeySr25519{}, sr25519.PubKeyAminoName, true},
{secp256k1.PubKeySecp256k1{}, secp256k1.PubKeyAminoName, true},
{bls.PubKeyBLS12{}, bls.PubKeyAminoName, true},
{composite.PubKeyComposite{}, composite.PubKeyAminoName, true},
{multisig.PubKeyMultisigThreshold{}, multisig.PubKeyMultisigThresholdAminoRoute, true},
}
for i, tc := range tests {
Expand Down
9 changes: 4 additions & 5 deletions libs/bech32/bech32.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
package bech32

import (
"github.com/btcsuite/btcutil/bech32"
"github.com/pkg/errors"
)

//ConvertAndEncode converts from a base64 encoded byte string to base32 encoded byte string and then to bech32
func ConvertAndEncode(hrp string, data []byte) (string, error) {
converted, err := bech32.ConvertBits(data, 8, 5, true)
converted, err := ConvertBits(data, 8, 5, true)
if err != nil {
return "", errors.Wrap(err, "encoding bech32 failed")
}
return bech32.Encode(hrp, converted)
return Encode(hrp, converted)

}

//DecodeAndConvert decodes a bech32 encoded string and converts to base64 encoded bytes
func DecodeAndConvert(bech string) (string, []byte, error) {
hrp, data, err := bech32.Decode(bech)
hrp, data, err := Decode(bech)
if err != nil {
return "", nil, errors.Wrap(err, "decoding bech32 failed")
}
converted, err := bech32.ConvertBits(data, 5, 8, false)
converted, err := ConvertBits(data, 5, 8, false)
if err != nil {
return "", nil, errors.Wrap(err, "decoding bech32 failed")
}
Expand Down
Loading