Skip to content

Commit

Permalink
fix: Implement gogoproto customtype to secp256r1 keys (backport #20027)…
Browse files Browse the repository at this point in the history
… (#20032)

Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com>
Co-authored-by: marbar3778 <marbar3778@yahoo.com>
Co-authored-by: Marko <marko@baricevic.me>
  • Loading branch information
4 people committed Apr 14, 2024
1 parent cdb519f commit af7ff74
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Bug Fixes

* (crypto) [#20027](https://github.com/cosmos/cosmos-sdk/pull/20027) secp256r1 keys now implement gogoproto's customtype interface.
* (x/gov) [#19725](https://github.com/cosmos/cosmos-sdk/pull/19725) Fetch a failed proposal tally from proposal.FinalTallyResult in the gprc query.
* (crypto) [#19691](https://github.com/cosmos/cosmos-sdk/pull/19746) Fix tx sign doesn't throw an error when incorrect Ledger is used.

Expand Down
25 changes: 25 additions & 0 deletions crypto/keys/secp256r1/privkey.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package secp256r1

import (
"encoding/base64"

"github.com/cosmos/cosmos-sdk/crypto/keys/internal/ecdsa"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)

var _ customProtobufType = (*ecdsaSK)(nil)

// GenPrivKey generates a new secp256r1 private key. It uses operating system randomness.
func GenPrivKey() (*PrivKey, error) {
key, err := ecdsa.GenPrivKey(secp256r1)
Expand Down Expand Up @@ -52,6 +56,27 @@ type ecdsaSK struct {
ecdsa.PrivKey
}

// Marshal implements customProtobufType.
func (sk ecdsaSK) Marshal() ([]byte, error) {
return sk.PrivKey.Bytes(), nil
}

// MarshalJSON implements customProtobufType.
func (sk ecdsaSK) MarshalJSON() ([]byte, error) {
b64 := base64.StdEncoding.EncodeToString(sk.PrivKey.Bytes())
return []byte(b64), nil
}

// UnmarshalJSON implements customProtobufType.
func (sk *ecdsaSK) UnmarshalJSON(data []byte) error {
bz, err := base64.StdEncoding.DecodeString(string(data))
if err != nil {
return err
}

return sk.PrivKey.Unmarshal(bz, secp256r1, fieldSize)
}

// Size implements proto.Marshaler interface
func (sk *ecdsaSK) Size() int {
if sk == nil {
Expand Down
11 changes: 11 additions & 0 deletions crypto/keys/secp256r1/privkey_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,14 @@ func (suite *SKSuite) TestSize() {
var nilPk *ecdsaSK
require.Equal(0, nilPk.Size(), "nil value must have zero size")
}

func (suite *SKSuite) TestJson() {
require := suite.Require()
asd := suite.sk.(*PrivKey)
bz, err := asd.Secret.MarshalJSON()
require.NoError(err)

sk := &ecdsaSK{}
require.NoError(sk.UnmarshalJSON(bz))
require.Equal(suite.sk.(*PrivKey).Secret, sk)
}
37 changes: 37 additions & 0 deletions crypto/keys/secp256r1/pubkey.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
package secp256r1

import (
"encoding/base64"

tmcrypto "github.com/cometbft/cometbft/crypto"
"github.com/cosmos/gogoproto/proto"

ecdsa "github.com/cosmos/cosmos-sdk/crypto/keys/internal/ecdsa"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)

// customProtobufType is here to make sure that ecdsaPK and ecdsaSK implement the
// gogoproto customtype interface.
type customProtobufType interface {
Marshal() ([]byte, error)
MarshalTo(data []byte) (n int, err error)
Unmarshal(data []byte) error
Size() int

MarshalJSON() ([]byte, error)
UnmarshalJSON(data []byte) error
}

var _ customProtobufType = (*ecdsaPK)(nil)

// String implements proto.Message interface.
func (m *PubKey) String() string {
return m.Key.String(name)
Expand Down Expand Up @@ -49,6 +65,27 @@ type ecdsaPK struct {
ecdsa.PubKey
}

// Marshal implements customProtobufType.
func (pk ecdsaPK) Marshal() ([]byte, error) {
return pk.PubKey.Bytes(), nil
}

// MarshalJSON implements customProtobufType.
func (pk ecdsaPK) MarshalJSON() ([]byte, error) {
b64 := base64.StdEncoding.EncodeToString(pk.PubKey.Bytes())
return []byte(b64), nil
}

// UnmarshalJSON implements customProtobufType.
func (pk *ecdsaPK) UnmarshalJSON(data []byte) error {
bz, err := base64.StdEncoding.DecodeString(string(data))
if err != nil {
return err
}

return pk.PubKey.Unmarshal(bz, secp256r1, pubKeySize)
}

// Size implements proto.Marshaler interface
func (pk *ecdsaPK) Size() int {
if pk == nil {
Expand Down
11 changes: 11 additions & 0 deletions crypto/keys/secp256r1/pubkey_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,14 @@ func (suite *PKSuite) TestSize() {
var nilPk *ecdsaPK
require.Equal(0, nilPk.Size(), "nil value must have zero size")
}

func (suite *PKSuite) TestJson() {
require := suite.Require()

bz, err := suite.pk.Key.MarshalJSON()
require.NoError(err)

pk := &ecdsaPK{}
require.NoError(pk.UnmarshalJSON(bz))
require.Equal(suite.pk.Key, pk)
}

0 comments on commit af7ff74

Please sign in to comment.