From 7fe75d2cd9f3f46c040ca962f47366e215fa24bb Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Tue, 19 Apr 2022 10:39:50 +0300 Subject: [PATCH] [#190] crypto: Replace public key encoding methods to `PublicKey` This make `neofscrypto.Signer` interface more similar to the one from standard `crypto` package. Signed-off-by: Leonard Lyubich --- crypto/ecdsa/public.go | 27 ++++++++++++++++++++++++++- crypto/ecdsa/signer.go | 22 ++++++---------------- crypto/signature.go | 6 ++++-- crypto/signer.go | 39 ++++++++++++++++++++------------------- 4 files changed, 56 insertions(+), 38 deletions(-) diff --git a/crypto/ecdsa/public.go b/crypto/ecdsa/public.go index ddaf413..c6d32dc 100644 --- a/crypto/ecdsa/public.go +++ b/crypto/ecdsa/public.go @@ -5,6 +5,7 @@ import ( "crypto/elliptic" "crypto/sha256" "crypto/sha512" + "fmt" "math/big" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -21,6 +22,11 @@ type PublicKey struct { key ecdsa.PublicKey } +// SetKey specifies ecdsa.PublicKey to be used for ECDSA signature verification. +func (x *PublicKey) SetKey(key ecdsa.PublicKey) { + x.key = key +} + // MakeDeterministic makes PublicKey to use Deterministic ECDSA scheme // (see neofscrypto.ECDSA_DETERMINISTIC_SHA256). By default, // neofscrypto.ECDSA_SHA512 is used. @@ -28,9 +34,28 @@ func (x *PublicKey) MakeDeterministic() { x.deterministic = true } +// MaxEncodedSize returns size of the compressed ECDSA public key. +func (x PublicKey) MaxEncodedSize() int { + return 33 +} + +// Encode encodes ECDSA public key in compressed form into buf. +// Uses exactly MaxEncodedSize bytes of the buf. +// +// Encode panics if buf length is less than MaxEncodedSize. +// +// See also Decode. +func (x PublicKey) Encode(buf []byte) int { + if len(buf) < 33 { + panic(fmt.Sprintf("too short buffer %d", len(buf))) + } + + return copy(buf, (*keys.PublicKey)(&x.key).Bytes()) +} + // Decode decodes compressed binary representation of the PublicKey. // -// See also Signer.EncodePublicKey. +// See also Encode. func (x *PublicKey) Decode(data []byte) error { pub, err := keys.NewPublicKeyFromBytes(data, elliptic.P256()) if err != nil { diff --git a/crypto/ecdsa/signer.go b/crypto/ecdsa/signer.go index 4f4247a..4271530 100644 --- a/crypto/ecdsa/signer.go +++ b/crypto/ecdsa/signer.go @@ -5,7 +5,6 @@ import ( "crypto/elliptic" "crypto/rand" "crypto/sha512" - "fmt" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" @@ -65,22 +64,13 @@ func (x Signer) Sign(data []byte) ([]byte, error) { return elliptic.Marshal(elliptic.P256(), r, s), nil } -// MaxPublicKeyEncodedSize returns size of the compressed ECDSA public key -// of the Signer. -func (x Signer) MaxPublicKeyEncodedSize() int { - return 33 -} +func (x Signer) Public() neofscrypto.PublicKey { + var pub PublicKey + pub.SetKey(x.key.PublicKey) -// EncodePublicKey encodes ECDSA public key of the Signer in compressed form -// into buf. Uses exactly MaxPublicKeyEncodedSize bytes of the buf. -// -// EncodePublicKey panics if buf length is less than MaxPublicKeyEncodedSize. -// -// See also PublicKey.Decode. -func (x Signer) EncodePublicKey(buf []byte) int { - if len(buf) < 33 { - panic(fmt.Sprintf("too short buffer %d", len(buf))) + if x.deterministic { + pub.MakeDeterministic() } - return copy(buf, (*keys.PublicKey)(&x.key.PublicKey).Bytes()) + return &pub } diff --git a/crypto/signature.go b/crypto/signature.go index 8718505..237176b 100644 --- a/crypto/signature.go +++ b/crypto/signature.go @@ -43,8 +43,10 @@ func (x *Signature) Calculate(signer Signer, data []byte) error { return fmt.Errorf("signer %T failure: %w", signer, err) } - key := make([]byte, signer.MaxPublicKeyEncodedSize()) - key = key[:signer.EncodePublicKey(key)] + pub := signer.Public() + + key := make([]byte, pub.MaxEncodedSize()) + key = key[:pub.Encode(key)] m := (*refs.Signature)(x) diff --git a/crypto/signer.go b/crypto/signer.go index 994ad86..ccd8a07 100644 --- a/crypto/signer.go +++ b/crypto/signer.go @@ -55,23 +55,8 @@ type Signer interface { // Sign signs SHA-256 hash of the data. Sign(data []byte) ([]byte, error) - // MaxPublicKeyEncodedSize returns maximum size required for binary-encoded - // public key. - // - // MaxPublicKeyEncodedSize MUST NOT return value greater than any return of - // EncodePublicKey. - MaxPublicKeyEncodedSize() int - - // EncodePublicKey encodes public key into buf. Returns number of bytes - // written. - // - // EncodePublicKey MUST panic if buffer size is insufficient and less than - // MaxPublicKeyEncodedSize (*). EncodePublicKey MUST return negative value - // on any failure except (*). - // - // EncodePublicKey is expected to be compatible with PublicKey.Decode for - // similar signature schemes. - EncodePublicKey(buf []byte) int + // Public returns the public key corresponding to the Signer. + Public() PublicKey } // PublicKey represents a public key using fixed signature scheme supported by @@ -79,10 +64,26 @@ type Signer interface { // // See also Signer. type PublicKey interface { + // MaxEncodedSize returns maximum size required for binary-encoded + // public key. + // + // MaxEncodedSize MUST NOT return value greater than any return of + // Encode. + MaxEncodedSize() int + + // Encode encodes public key into buf. Returns number of bytes + // written. + // + // Encode MUST panic if buffer size is insufficient and less than + // MaxEncodedSize (*). Encode MUST return negative value + // on any failure except (*). + // + // Encode is a reverse operation to Decode. + Encode(buf []byte) int + // Decode decodes binary public key. // - // Decode is expected to be compatible with Signer.EncodePublicKey for - // similar signature schemes. + // Decode is a reverse operation to Encode. Decode([]byte) error // Verify checks signature of the given data. True means correct signature.