[#157] signature: Change scheme selection

`SignData`: use `ECDSAWithSHA512` by default. `SignWithRFC6979` option
switches the scheme to `RFC6979WithSHA256`.

`VerifyData`: if scheme is not fixed (like by `SignWithRFC6979` option)
then scheme from the message is processed.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-03-02 13:41:41 +03:00 committed by Alex Vanin
parent 2a0b7b6b40
commit a292150d42
5 changed files with 18 additions and 20 deletions

2
go.mod
View file

@ -10,7 +10,7 @@ require (
github.com/mr-tron/base58 v1.2.0 github.com/mr-tron/base58 v1.2.0
github.com/nspcc-dev/hrw v1.0.9 github.com/nspcc-dev/hrw v1.0.9
github.com/nspcc-dev/neo-go v0.98.0 github.com/nspcc-dev/neo-go v0.98.0
github.com/nspcc-dev/neofs-api-go/v2 v2.12.0 github.com/nspcc-dev/neofs-api-go/v2 v2.11.2-0.20220302134950-d065453bd0a7
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
go.uber.org/zap v1.18.1 go.uber.org/zap v1.18.1
google.golang.org/grpc v1.41.0 google.golang.org/grpc v1.41.0

BIN
go.sum

Binary file not shown.

View file

@ -12,11 +12,14 @@ type Scheme uint32
// Supported signature schemes. // Supported signature schemes.
const ( const (
Unspecified Scheme = iota ECDSAWithSHA512 Scheme = iota
ECDSAWithSHA512
RFC6979WithSHA256 RFC6979WithSHA256
) )
func (x Scheme) String() string {
return refs.SignatureScheme(x).String()
}
// NewFromV2 wraps v2 Signature message to Signature. // NewFromV2 wraps v2 Signature message to Signature.
// //
// Nil refs.Signature converts to nil. // Nil refs.Signature converts to nil.

View file

@ -57,7 +57,7 @@ func SignData(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) (*signa
cfg := getConfig(opts...) cfg := getConfig(opts...)
sigData, err := sign(cfg.defaultScheme, key, data) sigData, err := sign(cfg.scheme, key, data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -65,7 +65,7 @@ func SignData(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) (*signa
sig := signature.New() sig := signature.New()
sig.SetKey((*keys.PublicKey)(&key.PublicKey).Bytes()) sig.SetKey((*keys.PublicKey)(&key.PublicKey).Bytes())
sig.SetSign(sigData) sig.SetSign(sigData)
sig.SetScheme(cfg.defaultScheme) sig.SetScheme(cfg.scheme)
return sig, nil return sig, nil
} }

View file

@ -16,14 +16,13 @@ import (
var curve = elliptic.P256() var curve = elliptic.P256()
type cfg struct { type cfg struct {
defaultScheme signature.Scheme schemeFixed bool
restrictScheme signature.Scheme scheme signature.Scheme
} }
func getConfig(opts ...SignOption) *cfg { func getConfig(opts ...SignOption) *cfg {
cfg := &cfg{ cfg := &cfg{
defaultScheme: signature.ECDSAWithSHA512, scheme: signature.ECDSAWithSHA512,
restrictScheme: signature.Unspecified,
} }
for i := range opts { for i := range opts {
@ -46,7 +45,7 @@ func sign(scheme signature.Scheme, key *ecdsa.PrivateKey, msg []byte) ([]byte, e
p := &keys.PrivateKey{PrivateKey: *key} p := &keys.PrivateKey{PrivateKey: *key}
return p.Sign(msg), nil return p.Sign(msg), nil
default: default:
panic("unsupported scheme") panic(fmt.Sprintf("unsupported scheme %s", scheme))
} }
} }
@ -56,15 +55,11 @@ func verify(cfg *cfg, msg []byte, sig *signature.Signature) error {
return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err) return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err)
} }
scheme := sig.Scheme() if !cfg.schemeFixed {
if scheme == signature.Unspecified { cfg.scheme = sig.Scheme()
scheme = cfg.defaultScheme
}
if cfg.restrictScheme != signature.Unspecified && scheme != cfg.restrictScheme {
return fmt.Errorf("%w: unexpected signature scheme", ErrInvalidSignature)
} }
switch scheme { switch cfg.scheme {
case signature.ECDSAWithSHA512: case signature.ECDSAWithSHA512:
h := sha512.Sum512(msg) h := sha512.Sum512(msg)
r, s := unmarshalXY(sig.Sign()) r, s := unmarshalXY(sig.Sign())
@ -79,7 +74,7 @@ func verify(cfg *cfg, msg []byte, sig *signature.Signature) error {
} }
return ErrInvalidSignature return ErrInvalidSignature
default: default:
return ErrInvalidSignature return fmt.Errorf("unsupported signature scheme %s", cfg.scheme)
} }
} }
@ -111,7 +106,7 @@ func unmarshalXY(data []byte) (x *big.Int, y *big.Int) {
func SignWithRFC6979() SignOption { func SignWithRFC6979() SignOption {
return func(c *cfg) { return func(c *cfg) {
c.defaultScheme = signature.RFC6979WithSHA256 c.schemeFixed = true
c.restrictScheme = signature.RFC6979WithSHA256 c.scheme = signature.RFC6979WithSHA256
} }
} }