[#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 <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-04-19 10:39:50 +03:00 committed by LeL
parent bcbffd516a
commit 7fe75d2cd9
4 changed files with 56 additions and 38 deletions

View file

@ -5,6 +5,7 @@ import (
"crypto/elliptic" "crypto/elliptic"
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
"fmt"
"math/big" "math/big"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -21,6 +22,11 @@ type PublicKey struct {
key ecdsa.PublicKey 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 // MakeDeterministic makes PublicKey to use Deterministic ECDSA scheme
// (see neofscrypto.ECDSA_DETERMINISTIC_SHA256). By default, // (see neofscrypto.ECDSA_DETERMINISTIC_SHA256). By default,
// neofscrypto.ECDSA_SHA512 is used. // neofscrypto.ECDSA_SHA512 is used.
@ -28,9 +34,28 @@ func (x *PublicKey) MakeDeterministic() {
x.deterministic = true 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. // Decode decodes compressed binary representation of the PublicKey.
// //
// See also Signer.EncodePublicKey. // See also Encode.
func (x *PublicKey) Decode(data []byte) error { func (x *PublicKey) Decode(data []byte) error {
pub, err := keys.NewPublicKeyFromBytes(data, elliptic.P256()) pub, err := keys.NewPublicKeyFromBytes(data, elliptic.P256())
if err != nil { if err != nil {

View file

@ -5,7 +5,6 @@ import (
"crypto/elliptic" "crypto/elliptic"
"crypto/rand" "crypto/rand"
"crypto/sha512" "crypto/sha512"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" 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 return elliptic.Marshal(elliptic.P256(), r, s), nil
} }
// MaxPublicKeyEncodedSize returns size of the compressed ECDSA public key func (x Signer) Public() neofscrypto.PublicKey {
// of the Signer. var pub PublicKey
func (x Signer) MaxPublicKeyEncodedSize() int { pub.SetKey(x.key.PublicKey)
return 33
}
// EncodePublicKey encodes ECDSA public key of the Signer in compressed form if x.deterministic {
// into buf. Uses exactly MaxPublicKeyEncodedSize bytes of the buf. pub.MakeDeterministic()
//
// 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)))
} }
return copy(buf, (*keys.PublicKey)(&x.key.PublicKey).Bytes()) return &pub
} }

View file

@ -43,8 +43,10 @@ func (x *Signature) Calculate(signer Signer, data []byte) error {
return fmt.Errorf("signer %T failure: %w", signer, err) return fmt.Errorf("signer %T failure: %w", signer, err)
} }
key := make([]byte, signer.MaxPublicKeyEncodedSize()) pub := signer.Public()
key = key[:signer.EncodePublicKey(key)]
key := make([]byte, pub.MaxEncodedSize())
key = key[:pub.Encode(key)]
m := (*refs.Signature)(x) m := (*refs.Signature)(x)

View file

@ -55,23 +55,8 @@ type Signer interface {
// Sign signs SHA-256 hash of the data. // Sign signs SHA-256 hash of the data.
Sign(data []byte) ([]byte, error) Sign(data []byte) ([]byte, error)
// MaxPublicKeyEncodedSize returns maximum size required for binary-encoded // Public returns the public key corresponding to the Signer.
// public key. Public() PublicKey
//
// 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
} }
// PublicKey represents a public key using fixed signature scheme supported by // PublicKey represents a public key using fixed signature scheme supported by
@ -79,10 +64,26 @@ type Signer interface {
// //
// See also Signer. // See also Signer.
type PublicKey interface { 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 decodes binary public key.
// //
// Decode is expected to be compatible with Signer.EncodePublicKey for // Decode is a reverse operation to Encode.
// similar signature schemes.
Decode([]byte) error Decode([]byte) error
// Verify checks signature of the given data. True means correct signature. // Verify checks signature of the given data. True means correct signature.