fix: Implement gogoproto customtype to secp256r1 keys (backport #20027) (#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>
This commit is contained in:
mergify[bot] 2024-04-14 08:59:30 +02:00 committed by GitHub
parent cdb519fa53
commit af7ff74fc4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 85 additions and 0 deletions

View File

@ -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.

View File

@ -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)
@ -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 {

View File

@ -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)
}

View File

@ -1,6 +1,8 @@
package secp256r1
import (
"encoding/base64"
tmcrypto "github.com/cometbft/cometbft/crypto"
"github.com/cosmos/gogoproto/proto"
@ -8,6 +10,20 @@ import (
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)
@ -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 {

View File

@ -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)
}