Skip to content

Commit

Permalink
fix: backport secp256r1 keys fix to lsm (#20073)
Browse files Browse the repository at this point in the history
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
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
5 people authored Apr 17, 2024
1 parent 14f041a commit 45931e7
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 1 deletion.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ Ref: https://keepachangelog.com/en/1.0.0/

# Changelog

## v0.47.12-ics-lsm

This is a special cosmos-sdk release with support for both ICS and LSM.

### Bugfixes

* (crypto) [#20073](https://github.com/cosmos/cosmos-sdk/pull/20073) Add secp256r1 parsing support (backport from main)


## v0.47.11-ics-lsm

This is a special cosmos-sdk release with support for both ICS and LSM.
Expand Down Expand Up @@ -511,4 +520,4 @@ extension interfaces. `module.Manager.Modules` is now of type `map[string]interf

## Previous Versions

[CHANGELOG of previous versions](https://github.com/cosmos/cosmos-sdk/blob/main/CHANGELOG.md#v0460---2022-07-26).
[CHANGELOG of previous versions](https://github.com/cosmos/cosmos-sdk/blob/main/CHANGELOG.md#v0460---2022-07-26).
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[1 : len(data)-1]))
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)
}
38 changes: 38 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,28 @@ 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 {
// the string is quoted so we need to remove them
bz, err := base64.StdEncoding.DecodeString(string(data[1 : len(data)-1]))
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 45931e7

Please sign in to comment.