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
|
@ -9,38 +9,65 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||
)
|
||||
|
||||
var curve = elliptic.P256()
|
||||
|
||||
type cfg struct {
|
||||
signFunc func(key *ecdsa.PrivateKey, msg []byte) ([]byte, error)
|
||||
verifyFunc func(key *ecdsa.PublicKey, msg []byte, sig []byte) error
|
||||
defaultScheme signature.Scheme
|
||||
restrictScheme signature.Scheme
|
||||
}
|
||||
|
||||
func defaultCfg() *cfg {
|
||||
return &cfg{
|
||||
signFunc: sign,
|
||||
verifyFunc: verify,
|
||||
func getConfig(opts ...SignOption) *cfg {
|
||||
cfg := &cfg{
|
||||
defaultScheme: signature.ECDSAWithSHA512,
|
||||
restrictScheme: signature.Unspecified,
|
||||
}
|
||||
|
||||
for i := range opts {
|
||||
opts[i](cfg)
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func sign(scheme signature.Scheme, key *ecdsa.PrivateKey, msg []byte) ([]byte, error) {
|
||||
switch scheme {
|
||||
case signature.ECDSAWithSHA512:
|
||||
h := sha512.Sum512(msg)
|
||||
x, y, err := ecdsa.Sign(rand.Reader, key, h[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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 sign(key *ecdsa.PrivateKey, msg []byte) ([]byte, error) {
|
||||
h := sha512.Sum512(msg)
|
||||
x, y, err := ecdsa.Sign(rand.Reader, key, h[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func verify(scheme signature.Scheme, key *ecdsa.PublicKey, msg []byte, sig []byte) error {
|
||||
switch scheme {
|
||||
case signature.ECDSAWithSHA512:
|
||||
h := sha512.Sum512(msg)
|
||||
r, s := unmarshalXY(sig)
|
||||
if r != nil && s != nil && ecdsa.Verify(key, h[:], r, s) {
|
||||
return nil
|
||||
}
|
||||
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
|
||||
}
|
||||
return elliptic.Marshal(elliptic.P256(), x, y), nil
|
||||
}
|
||||
|
||||
func verify(key *ecdsa.PublicKey, msg []byte, sig []byte) error {
|
||||
h := sha512.Sum512(msg)
|
||||
r, s := unmarshalXY(sig)
|
||||
if r != nil && s != nil && ecdsa.Verify(key, h[:], r, s) {
|
||||
return nil
|
||||
}
|
||||
return ErrInvalidSignature
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return func(c *cfg) {
|
||||
c.signFunc = signRFC6979
|
||||
c.verifyFunc = verifyRFC6979
|
||||
c.defaultScheme = signature.RFC6979WithSHA256
|
||||
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…
Add table
Add a link
Reference in a new issue