From f3ab3075b3aa36cfe1a3962a522d46274911fa80 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Sat, 29 Jul 2023 08:46:04 +0400 Subject: [PATCH] user: Refactor constructors of Signer instances Previously, package provided constructors for `Signer` instances with RFC 6979 signature scheme only. User may need to construct any `Signer` instance (other scheme or even custom implementation). Add generic constructor `NewSigner` accepting split `neofscrypto.Signer` and `user.ID`. Add two constructors from standard `ecdsa.PrivateKey` with an explanation that the user ID is resolved automatically. Signed-off-by: Leonard Lyubich --- client/example_container_put_test.go | 2 +- crypto/test/tests.go | 2 +- object/slicer/slicer_test.go | 2 +- pool/example_pool_test.go | 4 +- user/signer.go | 75 +++++++++++++--------------- waiter/example_waiter_test.go | 2 +- 6 files changed, 40 insertions(+), 47 deletions(-) diff --git a/client/example_container_put_test.go b/client/example_container_put_test.go index 08c2e454..3f8f6a39 100644 --- a/client/example_container_put_test.go +++ b/client/example_container_put_test.go @@ -25,7 +25,7 @@ func ExampleClient_ContainerPut() { panic(err) } - signer := user.NewSignerRFC6979(key.PrivateKey) + signer := user.NewAutoIDSignerRFC6979(key.PrivateKey) // take account from user's signer accountID = signer.UserID() diff --git a/crypto/test/tests.go b/crypto/test/tests.go index cb321ddd..f9135073 100644 --- a/crypto/test/tests.go +++ b/crypto/test/tests.go @@ -30,5 +30,5 @@ func RandomSignerRFC6979(tb testing.TB) user.Signer { p, err := keys.NewPrivateKey() require.NoError(tb, err) - return user.NewSignerRFC6979(p.PrivateKey) + return user.NewAutoIDSignerRFC6979(p.PrivateKey) } diff --git a/object/slicer/slicer_test.go b/object/slicer/slicer_test.go index 6d2e949e..b4e520cb 100644 --- a/object/slicer/slicer_test.go +++ b/object/slicer/slicer_test.go @@ -220,7 +220,7 @@ func randomInput(tb testing.TB, size, sizeLimit uint64) (input, slicer.Options) } var in input - in.signer = user.NewSignerRFC6979(*key) + in.signer = user.NewAutoIDSigner(*key) in.container = cidtest.ID() in.currentEpoch = rand.Uint64() if sizeLimit > 0 { diff --git a/pool/example_pool_test.go b/pool/example_pool_test.go index d47bc32c..22246ca8 100644 --- a/pool/example_pool_test.go +++ b/pool/example_pool_test.go @@ -13,7 +13,7 @@ import ( func ExampleNew_easiestWay() { // Signer generation, like example. pk, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - signer := user.NewSignerRFC6979(*pk) + signer := user.NewAutoIDSignerRFC6979(*pk) pool, _ := New(NewFlatNodeParams([]string{"grpc://localhost:8080", "grpcs://localhost:8081"}), signer, DefaultOptions()) _ = pool @@ -24,7 +24,7 @@ func ExampleNew_easiestWay() { func ExampleNew_adjustingParameters() { // Signer generation, like example. pk, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - signer := user.NewSignerRFC6979(*pk) + signer := user.NewAutoIDSignerRFC6979(*pk) opts := DefaultOptions() opts.SetErrorThreshold(10) diff --git a/user/signer.go b/user/signer.go index 582a39d7..bc973b66 100644 --- a/user/signer.go +++ b/user/signer.go @@ -8,65 +8,58 @@ import ( neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa" ) -// Signer is an interface of entities that can be used for signing operations -// in NeoFS. It is the same as [neofscrypto.Signer], but has an extra method to retrieve [ID]. +// Signer represents a NeoFS user authorized by a digital signature. type Signer interface { + // Signer signs data on behalf of the user. neofscrypto.Signer - + // UserID returns ID of the associated user. UserID() ID } -// SignerRFC6979 wraps [ecdsa.PrivateKey] and represents signer based on deterministic -// ECDSA with SHA-256 hashing (RFC 6979). Provides [Signer] interface. -// -// Instances SHOULD be initialized with [NewSignerRFC6979] or [NewSignerRFC6979WithID]. -type SignerRFC6979 struct { - neofsecdsa.SignerRFC6979 - userID ID +type signer struct { + neofscrypto.Signer + usr ID } -// NewSignerRFC6979 is a constructor for [SignerRFC6979]. -func NewSignerRFC6979(pk ecdsa.PrivateKey) *SignerRFC6979 { - var id ID - id.SetScriptHash((*keys.PublicKey)(&pk.PublicKey).GetScriptHash()) - - return &SignerRFC6979{ - userID: id, - SignerRFC6979: neofsecdsa.SignerRFC6979(pk), - } +func (s signer) UserID() ID { + return s.usr } -// NewSignerRFC6979WithID is a constructor for [SignerRFC6979] where you may specify [ID] associated with this signer. -func NewSignerRFC6979WithID(pk ecdsa.PrivateKey, id ID) *SignerRFC6979 { - return &SignerRFC6979{ - SignerRFC6979: neofsecdsa.SignerRFC6979(pk), - userID: id, +// NewSigner combines provided [neofscrypto.Signer] and [ID] into [Signer]. +// +// See also [NewAutoIDSigner]. +func NewSigner(s neofscrypto.Signer, usr ID) Signer { + return signer{ + Signer: s, + usr: usr, } } -// UserID returns the [ID] using script hash calculated for the given key. -func (s SignerRFC6979) UserID() ID { - return s.userID +func newAutoResolvedSigner(s neofscrypto.Signer, pubKey ecdsa.PublicKey) Signer { + var id ID + id.SetScriptHash((*keys.PublicKey)(&pubKey).GetScriptHash()) + + return NewSigner(s, id) } -// StaticSigner emulates real sign and contains already precalculated hash. -// Provides [Signer] interface. -type StaticSigner struct { - neofscrypto.StaticSigner - id ID +// NewAutoIDSigner returns [Signer] with neofscrypto.ECDSA_SHA512 +// signature scheme and user [ID] automatically resolved from the ECDSA public +// key. +// +// See also [NewAutoIDSignerRFC6979]. +func NewAutoIDSigner(key ecdsa.PrivateKey) Signer { + return newAutoResolvedSigner(neofsecdsa.Signer(key), key.PublicKey) } -// NewStaticSignerWithID creates new StaticSigner with specified [ID]. -func NewStaticSignerWithID(scheme neofscrypto.Scheme, sig []byte, pubKey neofscrypto.PublicKey, id ID) *StaticSigner { - return &StaticSigner{ - StaticSigner: *neofscrypto.NewStaticSigner(scheme, sig, pubKey), - id: id, - } +// NewAutoIDSignerRFC6979 is an analogue of [NewAutoIDSigner] but with +// [neofscrypto.ECDSA_DETERMINISTIC_SHA256] signature scheme. +func NewAutoIDSignerRFC6979(key ecdsa.PrivateKey) Signer { + return newAutoResolvedSigner(neofsecdsa.SignerRFC6979(key), key.PublicKey) } -// UserID returns underlying [ID]. -func (s *StaticSigner) UserID() ID { - return s.id +// NewStaticSignerWithID creates new [Signer] with specified [ID]. +func NewStaticSignerWithID(scheme neofscrypto.Scheme, sig []byte, pubKey neofscrypto.PublicKey, id ID) Signer { + return NewSigner(neofscrypto.NewStaticSigner(scheme, sig, pubKey), id) } // ResolveFromECDSAPublicKey resolves [ID] from the given [ecdsa.PublicKey]. diff --git a/waiter/example_waiter_test.go b/waiter/example_waiter_test.go index ec865c6e..a6e58ae0 100644 --- a/waiter/example_waiter_test.go +++ b/waiter/example_waiter_test.go @@ -24,7 +24,7 @@ func ExampleNewWaiter() { panic(err) } - signer := user.NewSignerRFC6979(key.PrivateKey) + signer := user.NewAutoIDSignerRFC6979(key.PrivateKey) account := signer.UserID()