forked from TrueCloudLab/frostfs-sdk-go
[#150] signature: Add scheme
Allow `SignOption` to set 2 parameters: 1. Default signature scheme, which is used in case scheme is unspecified. 2. Restrict scheme option which also checks that scheme is either unspecified or equal to the restricted scheme. This is only used for verification and is necessary because some of the signatures are used in smart-contracts. Also provide signature struct to sign/verify functions in helpers. The constant names differ a bit from those in API because of linter complaints. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
4fba1af6aa
commit
1c7dd03cf5
8 changed files with 129 additions and 131 deletions
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
v2container "github.com/nspcc-dev/neofs-api-go/v2/container"
|
v2container "github.com/nspcc-dev/neofs-api-go/v2/container"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
||||||
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
|
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
|
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
|
||||||
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||||
|
@ -87,11 +86,8 @@ func (c *Client) ContainerPut(ctx context.Context, prm PrmContainerPut) (*ResCon
|
||||||
// sign container
|
// sign container
|
||||||
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainer()}
|
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetContainer()}
|
||||||
|
|
||||||
err := sigutil.SignDataWithHandler(c.opts.key, signWrapper, func(key []byte, sig []byte) {
|
err := sigutil.SignDataWithHandler(c.opts.key, signWrapper, func(sig *signature.Signature) {
|
||||||
containerSignature := new(refs.Signature)
|
reqBody.SetSignature(sig.ToV2())
|
||||||
containerSignature.SetKey(key)
|
|
||||||
containerSignature.SetSign(sig)
|
|
||||||
reqBody.SetSignature(containerSignature)
|
|
||||||
}, sigutil.SignWithRFC6979())
|
}, sigutil.SignWithRFC6979())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -402,11 +398,8 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
|
||||||
delContainerSignWrapper{
|
delContainerSignWrapper{
|
||||||
body: reqBody,
|
body: reqBody,
|
||||||
},
|
},
|
||||||
func(key []byte, sig []byte) {
|
func(sig *signature.Signature) {
|
||||||
containerSignature := new(refs.Signature)
|
reqBody.SetSignature(sig.ToV2())
|
||||||
containerSignature.SetKey(key)
|
|
||||||
containerSignature.SetSign(sig)
|
|
||||||
reqBody.SetSignature(containerSignature)
|
|
||||||
},
|
},
|
||||||
sigutil.SignWithRFC6979())
|
sigutil.SignWithRFC6979())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -599,11 +592,8 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
|
||||||
// sign the eACL table
|
// sign the eACL table
|
||||||
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetEACL()}
|
signWrapper := v2signature.StableMarshalerWrapper{SM: reqBody.GetEACL()}
|
||||||
|
|
||||||
err := sigutil.SignDataWithHandler(c.opts.key, signWrapper, func(key []byte, sig []byte) {
|
err := sigutil.SignDataWithHandler(c.opts.key, signWrapper, func(sig *signature.Signature) {
|
||||||
eaclSignature := new(refs.Signature)
|
reqBody.SetSignature(sig.ToV2())
|
||||||
eaclSignature.SetKey(key)
|
|
||||||
eaclSignature.SetSign(sig)
|
|
||||||
reqBody.SetSignature(eaclSignature)
|
|
||||||
}, sigutil.SignWithRFC6979())
|
}, sigutil.SignWithRFC6979())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -94,9 +94,8 @@ func CalculateIDSignature(key *ecdsa.PrivateKey, id *oid.ID) (*signature.Signatu
|
||||||
signatureV2.StableMarshalerWrapper{
|
signatureV2.StableMarshalerWrapper{
|
||||||
SM: id.ToV2(),
|
SM: id.ToV2(),
|
||||||
},
|
},
|
||||||
func(key, sign []byte) {
|
func(s *signature.Signature) {
|
||||||
sig.SetKey(key)
|
*sig = *s
|
||||||
sig.SetSign(sign)
|
|
||||||
},
|
},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -121,11 +120,7 @@ func VerifyIDSignature(obj *Object) error {
|
||||||
signatureV2.StableMarshalerWrapper{
|
signatureV2.StableMarshalerWrapper{
|
||||||
SM: obj.ID().ToV2(),
|
SM: obj.ID().ToV2(),
|
||||||
},
|
},
|
||||||
func() ([]byte, []byte) {
|
obj.Signature,
|
||||||
sig := obj.Signature()
|
|
||||||
|
|
||||||
return sig.Key(), sig.Sign()
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/reputation"
|
"github.com/nspcc-dev/neofs-api-go/v2/reputation"
|
||||||
signatureV2 "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
signatureV2 "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/util/signature"
|
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||||
|
sigutil "github.com/nspcc-dev/neofs-sdk-go/util/signature"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/version"
|
"github.com/nspcc-dev/neofs-sdk-go/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -259,18 +260,11 @@ func (x *GlobalTrust) Trust() *Trust {
|
||||||
func (x *GlobalTrust) Sign(key *ecdsa.PrivateKey) error {
|
func (x *GlobalTrust) Sign(key *ecdsa.PrivateKey) error {
|
||||||
v2 := (*reputation.GlobalTrust)(x)
|
v2 := (*reputation.GlobalTrust)(x)
|
||||||
|
|
||||||
sigV2 := v2.GetSignature()
|
return sigutil.SignDataWithHandler(
|
||||||
if sigV2 == nil {
|
|
||||||
sigV2 = new(refs.Signature)
|
|
||||||
v2.SetSignature(sigV2)
|
|
||||||
}
|
|
||||||
|
|
||||||
return signature.SignDataWithHandler(
|
|
||||||
key,
|
key,
|
||||||
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
||||||
func(key, sig []byte) {
|
func(sig *signature.Signature) {
|
||||||
sigV2.SetKey(key)
|
v2.SetSignature(sig.ToV2())
|
||||||
sigV2.SetSign(sig)
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -284,10 +278,10 @@ func (x *GlobalTrust) VerifySignature() error {
|
||||||
sigV2 = new(refs.Signature)
|
sigV2 = new(refs.Signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
return signature.VerifyDataWithSource(
|
return sigutil.VerifyDataWithSource(
|
||||||
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
||||||
func() ([]byte, []byte) {
|
func() *signature.Signature {
|
||||||
return sigV2.GetKey(), sigV2.GetSign()
|
return signature.NewFromV2(sigV2)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package session
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||||
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
||||||
|
@ -169,16 +168,8 @@ func (t *Token) Sign(key *ecdsa.PrivateKey) error {
|
||||||
SM: tV2.GetBody(),
|
SM: tV2.GetBody(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return sigutil.SignDataWithHandler(key, signedData, func(key, sig []byte) {
|
return sigutil.SignDataWithHandler(key, signedData, func(sig *signature.Signature) {
|
||||||
tSig := tV2.GetSignature()
|
tV2.SetSignature(sig.ToV2())
|
||||||
if tSig == nil {
|
|
||||||
tSig = new(refs.Signature)
|
|
||||||
}
|
|
||||||
|
|
||||||
tSig.SetKey(key)
|
|
||||||
tSig.SetSign(sig)
|
|
||||||
|
|
||||||
tV2.SetSignature(tSig)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,10 +182,7 @@ func (t *Token) VerifySignature() bool {
|
||||||
SM: tV2.GetBody(),
|
SM: tV2.GetBody(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return sigutil.VerifyDataWithSource(signedData, func() (key, sig []byte) {
|
return sigutil.VerifyDataWithSource(signedData, t.Signature) == nil
|
||||||
tSig := tV2.GetSignature()
|
|
||||||
return tSig.GetKey(), tSig.GetSign()
|
|
||||||
}) == nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signature returns Token signature.
|
// Signature returns Token signature.
|
||||||
|
|
|
@ -7,6 +7,16 @@ import (
|
||||||
// Signature represents v2-compatible signature.
|
// Signature represents v2-compatible signature.
|
||||||
type Signature refs.Signature
|
type Signature refs.Signature
|
||||||
|
|
||||||
|
// Scheme represents signature scheme.
|
||||||
|
type Scheme uint32
|
||||||
|
|
||||||
|
// Supported signature schemes.
|
||||||
|
const (
|
||||||
|
Unspecified Scheme = iota
|
||||||
|
ECDSAWithSHA512
|
||||||
|
RFC6979WithSHA256
|
||||||
|
)
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -43,6 +53,16 @@ func (s *Signature) SetSign(v []byte) {
|
||||||
(*refs.Signature)(s).SetSign(v)
|
(*refs.Signature)(s).SetSign(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scheme returns signature scheme.
|
||||||
|
func (s *Signature) Scheme() Scheme {
|
||||||
|
return Scheme((*refs.Signature)(s).GetScheme())
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetScheme sets signature scheme.
|
||||||
|
func (s *Signature) SetScheme(v Scheme) {
|
||||||
|
(*refs.Signature)(s).SetScheme(refs.SignatureScheme(v))
|
||||||
|
}
|
||||||
|
|
||||||
// ToV2 converts Signature to v2 Signature message.
|
// ToV2 converts Signature to v2 Signature message.
|
||||||
//
|
//
|
||||||
// Nil Signature converts to nil.
|
// Nil Signature converts to nil.
|
||||||
|
|
|
@ -7,12 +7,11 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
||||||
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||||
util "github.com/nspcc-dev/neofs-sdk-go/util/signature"
|
sigutil "github.com/nspcc-dev/neofs-sdk-go/util/signature"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -103,11 +102,8 @@ func (b *BearerToken) SignToken(key *ecdsa.PrivateKey) error {
|
||||||
|
|
||||||
signWrapper := v2signature.StableMarshalerWrapper{SM: b.token.GetBody()}
|
signWrapper := v2signature.StableMarshalerWrapper{SM: b.token.GetBody()}
|
||||||
|
|
||||||
return util.SignDataWithHandler(key, signWrapper, func(key []byte, sig []byte) {
|
return sigutil.SignDataWithHandler(key, signWrapper, func(sig *signature.Signature) {
|
||||||
bearerSignature := new(refs.Signature)
|
b.token.SetSignature(sig.ToV2())
|
||||||
bearerSignature.SetKey(key)
|
|
||||||
bearerSignature.SetSign(sig)
|
|
||||||
b.token.SetSignature(bearerSignature)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,11 +116,11 @@ func (b BearerToken) VerifySignature() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return util.VerifyDataWithSource(
|
return sigutil.VerifyDataWithSource(
|
||||||
v2signature.StableMarshalerWrapper{SM: b.token.GetBody()},
|
v2signature.StableMarshalerWrapper{SM: b.token.GetBody()},
|
||||||
func() (key, sig []byte) {
|
func() *signature.Signature {
|
||||||
sigV2 := b.token.GetSignature()
|
sigV2 := b.token.GetSignature()
|
||||||
return sigV2.GetKey(), sigV2.GetSign()
|
return signature.NewFromV2(sigV2)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DataSource interface {
|
type DataSource interface {
|
||||||
|
@ -16,15 +17,15 @@ type DataSource interface {
|
||||||
|
|
||||||
type DataWithSignature interface {
|
type DataWithSignature interface {
|
||||||
DataSource
|
DataSource
|
||||||
GetSignatureWithKey() (key, sig []byte)
|
GetSignature() *signature.Signature
|
||||||
SetSignatureWithKey(key, sig []byte)
|
SetSignature(*signature.Signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
type SignOption func(*cfg)
|
type SignOption func(*cfg)
|
||||||
|
|
||||||
type KeySignatureHandler func(key []byte, sig []byte)
|
type KeySignatureHandler func(*signature.Signature)
|
||||||
|
|
||||||
type KeySignatureSource func() (key, sig []byte)
|
type KeySignatureSource func() *signature.Signature
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// PrivateKeyCompressedSize is constant with compressed size of private key (SK).
|
// PrivateKeyCompressedSize is constant with compressed size of private key (SK).
|
||||||
|
@ -49,34 +50,30 @@ var (
|
||||||
ErrInvalidSignature = errors.New("invalid signature")
|
ErrInvalidSignature = errors.New("invalid signature")
|
||||||
)
|
)
|
||||||
|
|
||||||
func DataSignature(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) ([]byte, error) {
|
func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySignatureHandler, opts ...SignOption) error {
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return nil, ErrEmptyPrivateKey
|
return ErrEmptyPrivateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := dataForSignature(src)
|
data, err := dataForSignature(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
defer bytesPool.Put(&data)
|
defer bytesPool.Put(&data)
|
||||||
|
|
||||||
cfg := defaultCfg()
|
cfg := getConfig(opts...)
|
||||||
|
|
||||||
for i := range opts {
|
sigData, err := sign(cfg.defaultScheme, key, data)
|
||||||
opts[i](cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cfg.signFunc(key, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySignatureHandler, opts ...SignOption) error {
|
|
||||||
sig, err := DataSignature(key, src, opts...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pub := (*keys.PublicKey)(&key.PublicKey)
|
sig := signature.New()
|
||||||
handler(pub.Bytes(), sig)
|
sig.SetKey((*keys.PublicKey)(&key.PublicKey).Bytes())
|
||||||
|
sig.SetSign(sigData)
|
||||||
|
sig.SetScheme(cfg.defaultScheme)
|
||||||
|
|
||||||
|
handler(sig)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -88,33 +85,38 @@ func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ..
|
||||||
}
|
}
|
||||||
defer bytesPool.Put(&data)
|
defer bytesPool.Put(&data)
|
||||||
|
|
||||||
cfg := defaultCfg()
|
cfg := getConfig(opts...)
|
||||||
|
|
||||||
for i := range opts {
|
sig := sigSrc()
|
||||||
opts[i](cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
key, sig := sigSrc()
|
|
||||||
|
|
||||||
var pub *keys.PublicKey
|
var pub *keys.PublicKey
|
||||||
if len(key) != 0 {
|
if len(sig.Key()) != 0 {
|
||||||
pub, err = keys.NewPublicKeyFromBytes(key, elliptic.P256())
|
pub, err = keys.NewPublicKeyFromBytes(sig.Key(), elliptic.P256())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err)
|
return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg.verifyFunc(
|
scheme := sig.Scheme()
|
||||||
|
if scheme == signature.Unspecified {
|
||||||
|
scheme = cfg.defaultScheme
|
||||||
|
}
|
||||||
|
if cfg.restrictScheme != signature.Unspecified && scheme != cfg.restrictScheme {
|
||||||
|
return fmt.Errorf("%w: unexpected signature scheme", ErrInvalidSignature)
|
||||||
|
}
|
||||||
|
|
||||||
|
return verify(
|
||||||
|
scheme,
|
||||||
(*ecdsa.PublicKey)(pub),
|
(*ecdsa.PublicKey)(pub),
|
||||||
data,
|
data,
|
||||||
sig,
|
sig.Sign(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SignData(key *ecdsa.PrivateKey, v DataWithSignature, opts ...SignOption) error {
|
func SignData(key *ecdsa.PrivateKey, v DataWithSignature, opts ...SignOption) error {
|
||||||
return SignDataWithHandler(key, v, v.SetSignatureWithKey, opts...)
|
return SignDataWithHandler(key, v, v.SetSignature, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyData(src DataWithSignature, opts ...SignOption) error {
|
func VerifyData(src DataWithSignature, opts ...SignOption) error {
|
||||||
return VerifyDataWithSource(src, src.GetSignatureWithKey, opts...)
|
return VerifyDataWithSource(src, src.GetSignature, opts...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,38 +9,65 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||||
)
|
)
|
||||||
|
|
||||||
var curve = elliptic.P256()
|
var curve = elliptic.P256()
|
||||||
|
|
||||||
type cfg struct {
|
type cfg struct {
|
||||||
signFunc func(key *ecdsa.PrivateKey, msg []byte) ([]byte, error)
|
defaultScheme signature.Scheme
|
||||||
verifyFunc func(key *ecdsa.PublicKey, msg []byte, sig []byte) error
|
restrictScheme signature.Scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultCfg() *cfg {
|
func getConfig(opts ...SignOption) *cfg {
|
||||||
return &cfg{
|
cfg := &cfg{
|
||||||
signFunc: sign,
|
defaultScheme: signature.ECDSAWithSHA512,
|
||||||
verifyFunc: verify,
|
restrictScheme: signature.Unspecified,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := range opts {
|
||||||
|
opts[i](cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func sign(key *ecdsa.PrivateKey, msg []byte) ([]byte, error) {
|
func sign(scheme signature.Scheme, key *ecdsa.PrivateKey, msg []byte) ([]byte, error) {
|
||||||
|
switch scheme {
|
||||||
|
case signature.ECDSAWithSHA512:
|
||||||
h := sha512.Sum512(msg)
|
h := sha512.Sum512(msg)
|
||||||
x, y, err := ecdsa.Sign(rand.Reader, key, h[:])
|
x, y, err := ecdsa.Sign(rand.Reader, key, h[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return elliptic.Marshal(elliptic.P256(), x, y), nil
|
return elliptic.Marshal(elliptic.P256(), x, y), nil
|
||||||
|
case signature.RFC6979WithSHA256:
|
||||||
|
p := &keys.PrivateKey{PrivateKey: *key}
|
||||||
|
return p.Sign(msg), nil
|
||||||
|
default:
|
||||||
|
panic("unsupported scheme")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func verify(key *ecdsa.PublicKey, msg []byte, sig []byte) error {
|
func verify(scheme signature.Scheme, key *ecdsa.PublicKey, msg []byte, sig []byte) error {
|
||||||
|
switch scheme {
|
||||||
|
case signature.ECDSAWithSHA512:
|
||||||
h := sha512.Sum512(msg)
|
h := sha512.Sum512(msg)
|
||||||
r, s := unmarshalXY(sig)
|
r, s := unmarshalXY(sig)
|
||||||
if r != nil && s != nil && ecdsa.Verify(key, h[:], r, s) {
|
if r != nil && s != nil && ecdsa.Verify(key, h[:], r, s) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ErrInvalidSignature
|
return ErrInvalidSignature
|
||||||
|
case signature.RFC6979WithSHA256:
|
||||||
|
p := (*keys.PublicKey)(key)
|
||||||
|
h := sha256.Sum256(msg)
|
||||||
|
if p.Verify(sig, h[:]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ErrInvalidSignature
|
||||||
|
default:
|
||||||
|
return ErrInvalidSignature
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmarshalXY converts a point, serialized by Marshal, into an x, y pair.
|
// unmarshalXY converts a point, serialized by Marshal, into an x, y pair.
|
||||||
|
@ -71,21 +98,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.signFunc = signRFC6979
|
c.defaultScheme = signature.RFC6979WithSHA256
|
||||||
c.verifyFunc = verifyRFC6979
|
c.restrictScheme = signature.RFC6979WithSHA256
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func signRFC6979(key *ecdsa.PrivateKey, msg []byte) ([]byte, error) {
|
|
||||||
p := &keys.PrivateKey{PrivateKey: *key}
|
|
||||||
return p.Sign(msg), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifyRFC6979(key *ecdsa.PublicKey, msg []byte, sig []byte) error {
|
|
||||||
p := (*keys.PublicKey)(key)
|
|
||||||
h := sha256.Sum256(msg)
|
|
||||||
if p.Verify(sig, h[:]) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return ErrInvalidSignature
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue