Skip to content

Commit

Permalink
user: Refactor constructors of Signer instances
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
cthulhu-rider committed Aug 3, 2023
1 parent 223fe39 commit 75dfaef
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 31 deletions.
2 changes: 1 addition & 1 deletion client/example_container_put_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
2 changes: 1 addition & 1 deletion crypto/test/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
2 changes: 1 addition & 1 deletion object/slicer/slicer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,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 {
Expand Down
4 changes: 2 additions & 2 deletions pool/example_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
58 changes: 33 additions & 25 deletions user/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,51 @@ 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.
type signer struct {
neofscrypto.Signer
usr ID
}

func (s signer) UserID() ID {
return s.usr
}

// NewSigner combines provided [neofscrypto.Signer] and [ID] into [Signer].
//
// Instances SHOULD be initialized with [NewSignerRFC6979] or [NewSignerRFC6979WithID].
type SignerRFC6979 struct {
neofsecdsa.SignerRFC6979
userID ID
// See also [NewAutoIDSigner].
func NewSigner(s neofscrypto.Signer, usr ID) Signer {
return signer{
Signer: s,
usr: usr,
}
}

// NewSignerRFC6979 is a constructor for [SignerRFC6979].
func NewSignerRFC6979(pk ecdsa.PrivateKey) *SignerRFC6979 {
func newAutoResolvedSigner(s neofscrypto.Signer, pubKey ecdsa.PublicKey) Signer {
var id ID
id.SetScriptHash((*keys.PublicKey)(&pk.PublicKey).GetScriptHash())
id.SetScriptHash((*keys.PublicKey)(&pubKey).GetScriptHash())

return &SignerRFC6979{
userID: id,
SignerRFC6979: neofsecdsa.SignerRFC6979(pk),
}
return NewSigner(s, id)
}

// 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,
}
// 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)
}

// UserID returns the [ID] using script hash calculated for the given key.
func (s SignerRFC6979) UserID() ID {
return s.userID
// 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)
}
2 changes: 1 addition & 1 deletion waiter/example_waiter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func ExampleNewWaiter() {
panic(err)
}

signer := user.NewSignerRFC6979(key.PrivateKey)
signer := user.NewAutoIDSignerRFC6979(key.PrivateKey)

account := signer.UserID()

Expand Down

0 comments on commit 75dfaef

Please sign in to comment.