diff --git a/eacl/record_test.go b/eacl/record_test.go index dd33d50..3a26c0d 100644 --- a/eacl/record_test.go +++ b/eacl/record_test.go @@ -2,10 +2,11 @@ package eacl import ( "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" "fmt" "testing" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" checksumtest "github.com/nspcc-dev/neofs-sdk-go/checksum/test" cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test" @@ -251,8 +252,7 @@ func TestReservedRecords(t *testing.T) { } func randomPublicKey(t *testing.T) *ecdsa.PublicKey { - p, err := keys.NewPrivateKey() + p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, err) - - return (*ecdsa.PublicKey)(p.PublicKey()) + return &p.PublicKey } diff --git a/eacl/target.go b/eacl/target.go index 249628b..3a2b7a8 100644 --- a/eacl/target.go +++ b/eacl/target.go @@ -2,8 +2,8 @@ package eacl import ( "crypto/ecdsa" + "crypto/elliptic" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" ) @@ -51,7 +51,8 @@ func SetTargetECDSAKeys(t *Target, pubs ...*ecdsa.PublicKey) { } for i := 0; i < ln; i++ { - binKeys = append(binKeys, (*keys.PublicKey)(pubs[i]).Bytes()) + b := elliptic.MarshalCompressed(pubs[i].Curve, pubs[i].X, pubs[i].Y) + binKeys = append(binKeys, b) } t.SetBinaryKeys(binKeys) @@ -67,9 +68,13 @@ func TargetECDSAKeys(t *Target) []*ecdsa.PublicKey { pubs := make([]*ecdsa.PublicKey, ln) for i := 0; i < ln; i++ { - p := new(keys.PublicKey) - if p.DecodeBytes(binKeys[i]) == nil { - pubs[i] = (*ecdsa.PublicKey)(p) + x, y := elliptic.UnmarshalCompressed(elliptic.P256(), binKeys[i]) + if x != nil && y != nil { + pubs[i] = &ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: x, + Y: y, + } } } diff --git a/eacl/target_test.go b/eacl/target_test.go index 2afd6f9..d89c05d 100644 --- a/eacl/target_test.go +++ b/eacl/target_test.go @@ -2,9 +2,9 @@ package eacl import ( "crypto/ecdsa" + "crypto/elliptic" "testing" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-api-go/v2/acl" v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl" "github.com/stretchr/testify/require" @@ -25,7 +25,8 @@ func TestTarget(t *testing.T) { require.Equal(t, v2acl.RoleSystem, v2.GetRole()) require.Len(t, v2.GetKeys(), len(pubs)) for i, key := range v2.GetKeys() { - require.Equal(t, key, (*keys.PublicKey)(pubs[i]).Bytes()) + b := elliptic.MarshalCompressed(pubs[i].Curve, pubs[i].X, pubs[i].Y) + require.Equal(t, key, b) } newTarget := NewTargetFromV2(v2) diff --git a/go.mod b/go.mod index 3cc26de..e1eb55e 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,11 @@ require ( github.com/hashicorp/golang-lru v0.5.4 github.com/mr-tron/base58 v1.2.0 github.com/nspcc-dev/hrw v1.0.9 - github.com/nspcc-dev/neo-go v0.96.1 github.com/nspcc-dev/neofs-api-go v1.30.0 github.com/nspcc-dev/neofs-crypto v0.3.0 + github.com/nspcc-dev/rfc6979 v0.2.0 github.com/stretchr/testify v1.7.0 go.uber.org/zap v1.18.1 + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 google.golang.org/grpc v1.41.0 ) diff --git a/go.sum b/go.sum index c54d774..7fd1dfd 100644 Binary files a/go.sum and b/go.sum differ diff --git a/object/fmt_test.go b/object/fmt_test.go index 6e4bab7..d2fc57c 100644 --- a/object/fmt_test.go +++ b/object/fmt_test.go @@ -1,10 +1,11 @@ package object import ( + "crypto/ecdsa" + "crypto/elliptic" "crypto/rand" "testing" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/stretchr/testify/require" ) @@ -17,9 +18,9 @@ func TestVerificationFields(t *testing.T) { obj.SetPayload(payload) obj.SetPayloadSize(uint64(len(payload))) - p, err := keys.NewPrivateKey() + p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, err) - require.NoError(t, SetVerificationFields(&p.PrivateKey, obj)) + require.NoError(t, SetVerificationFields(p, obj)) require.NoError(t, CheckVerificationFields(obj.Object())) diff --git a/owner/id.go b/owner/id.go index 6aed52e..ba3113b 100644 --- a/owner/id.go +++ b/owner/id.go @@ -6,8 +6,6 @@ import ( "fmt" "github.com/mr-tron/base58" - "github.com/nspcc-dev/neo-go/pkg/crypto/hash" - "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neofs-api-go/v2/refs" ) @@ -96,12 +94,12 @@ func valid(rawID []byte) bool { if len(rawID) != NEO3WalletSize { return false } - if rawID[0] != address.NEO3Prefix { + if rawID[0] != addressPrefixN3 { return false } const boundIndex = NEO3WalletSize - 4 - return bytes.Equal(rawID[boundIndex:], hash.Checksum(rawID[:boundIndex])) + return bytes.Equal(rawID[boundIndex:], addressChecksum(rawID[:boundIndex])) } // Marshal marshals ID into a protobuf binary form. diff --git a/owner/id_test.go b/owner/id_test.go index 1737551..6493d7a 100644 --- a/owner/id_test.go +++ b/owner/id_test.go @@ -2,11 +2,11 @@ package owner_test import ( "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" "testing" "github.com/mr-tron/base58" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/util/slice" "github.com/nspcc-dev/neofs-api-go/v2/refs" . "github.com/nspcc-dev/neofs-sdk-go/owner" ownertest "github.com/nspcc-dev/neofs-sdk-go/owner/test" @@ -28,10 +28,11 @@ func TestID_Valid(t *testing.T) { val := id.ToV2().GetValue() t.Run("invalid prefix", func(t *testing.T) { - val := slice.Copy(val) - val[0] ^= 0xFF + v := make([]byte, len(val)) + copy(v, val) + v[0] ^= 0xFF - id := ownertest.GenerateIDFromBytes(val) + id := ownertest.GenerateIDFromBytes(v) require.False(t, id.Valid()) }) t.Run("invalid size", func(t *testing.T) { @@ -41,19 +42,20 @@ func TestID_Valid(t *testing.T) { require.False(t, id.Valid()) }) t.Run("invalid checksum", func(t *testing.T) { - val := slice.Copy(val) - val[NEO3WalletSize-1] ^= 0xFF + v := make([]byte, len(val)) + copy(v, val) + v[NEO3WalletSize-1] ^= 0xFF - id := ownertest.GenerateIDFromBytes(val) + id := ownertest.GenerateIDFromBytes(v) require.False(t, id.Valid()) }) } func TestNewIDFromNeo3Wallet(t *testing.T) { - p, err := keys.NewPrivateKey() + p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, err) - wallet, err := NEO3WalletFromPublicKey((*ecdsa.PublicKey)(p.PublicKey())) + wallet, err := NEO3WalletFromPublicKey(&p.PublicKey) require.NoError(t, err) id := NewIDFromNeo3Wallet(wallet) @@ -62,10 +64,10 @@ func TestNewIDFromNeo3Wallet(t *testing.T) { func TestID_Parse(t *testing.T) { t.Run("should parse successful", func(t *testing.T) { - p, err := keys.NewPrivateKey() + p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, err) - wallet, err := NEO3WalletFromPublicKey((*ecdsa.PublicKey)(p.PublicKey())) + wallet, err := NEO3WalletFromPublicKey(&p.PublicKey) require.NoError(t, err) eid := NewIDFromNeo3Wallet(wallet) diff --git a/owner/test/id.go b/owner/test/id.go index 0ffcd80..059c517 100644 --- a/owner/test/id.go +++ b/owner/test/id.go @@ -1,11 +1,9 @@ package ownertest import ( + "crypto/sha256" "math/rand" - "github.com/mr-tron/base58" - "github.com/nspcc-dev/neo-go/pkg/encoding/address" - "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-sdk-go/owner" ) @@ -13,15 +11,13 @@ import ( // GenerateID returns owner.ID calculated // from a random owner.NEO3Wallet. func GenerateID() *owner.ID { - u := util.Uint160{} - rand.Read(u[:]) - - addr := address.Uint160ToString(u) - data, err := base58.Decode(addr) - if err != nil { - panic(err) - } - return GenerateIDFromBytes(data) + u := make([]byte, owner.NEO3WalletSize) + u[0] = 0x35 + rand.Read(u[1:21]) + h1 := sha256.Sum256(u[:21]) + h2 := sha256.Sum256(h1[:]) + copy(u[21:], h2[:4]) + return GenerateIDFromBytes(u) } // GenerateIDFromBytes returns owner.ID generated diff --git a/owner/wallet.go b/owner/wallet.go index 3dfcb00..0a96578 100644 --- a/owner/wallet.go +++ b/owner/wallet.go @@ -2,11 +2,12 @@ package owner import ( "crypto/ecdsa" + "crypto/elliptic" + "crypto/sha256" "errors" - "fmt" "github.com/mr-tron/base58" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "golang.org/x/crypto/ripemd160" ) // NEO3Wallet represents NEO3 wallet address. @@ -15,6 +16,8 @@ type NEO3Wallet [NEO3WalletSize]byte // NEO3WalletSize contains size of neo3 wallet. const NEO3WalletSize = 25 +const addressPrefixN3 = 0x35 + // ErrEmptyPublicKey when PK passed to Verify method is nil. var ErrEmptyPublicKey = errors.New("empty public key") @@ -24,18 +27,30 @@ func NEO3WalletFromPublicKey(key *ecdsa.PublicKey) (*NEO3Wallet, error) { return nil, ErrEmptyPublicKey } - neoPublicKey := (*keys.PublicKey)(key) + b := elliptic.MarshalCompressed(key.Curve, key.X, key.Y) + script := []byte{0x0C /* PUSHDATA1 */, byte(len(b)) /* 33 */} + script = append(script, b...) + script = append(script, 0x41 /* SYSCALL */) + h := sha256.Sum256([]byte("System.Crypto.CheckSig")) + script = append(script, h[:4]...) - d, err := base58.Decode(neoPublicKey.Address()) - if err != nil { - return nil, fmt.Errorf("can't decode neo3 address from key: %w", err) - } + h1 := sha256.Sum256(script) + rw := ripemd160.New() + rw.Write(h1[:]) + h160 := rw.Sum(nil) - w := new(NEO3Wallet) + var w NEO3Wallet + w[0] = addressPrefixN3 + copy(w[1:21], h160) + copy(w[21:], addressChecksum(w[:21])) - copy(w.Bytes(), d) + return &w, nil +} - return w, nil +func addressChecksum(data []byte) []byte { + h1 := sha256.Sum256(data) + h2 := sha256.Sum256(h1[:]) + return h2[:4] } // String implements fmt.Stringer. diff --git a/pool/pool.go b/pool/pool.go index af0a3f3..1315d25 100644 --- a/pool/pool.go +++ b/pool/pool.go @@ -3,6 +3,7 @@ package pool import ( "context" "crypto/ecdsa" + "encoding/hex" "errors" "fmt" "math" @@ -11,7 +12,6 @@ import ( "sync" "time" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-sdk-go/client" "github.com/nspcc-dev/neofs-sdk-go/container" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" @@ -352,8 +352,9 @@ func (p *pool) OwnerID() *owner.ID { } func formCacheKey(address string, key *ecdsa.PrivateKey) string { - k := keys.PrivateKey{PrivateKey: *key} - return address + k.String() + buf := make([]byte, 32) + key.D.FillBytes(buf) + return address + hex.EncodeToString(buf) } func (p *pool) conn(ctx context.Context, cfg *callConfig) (*clientPack, []client.CallOption, error) { diff --git a/pool/pool_test.go b/pool/pool_test.go index f0e29d6..d476afa 100644 --- a/pool/pool_test.go +++ b/pool/pool_test.go @@ -4,6 +4,9 @@ package pool import ( "context" + "crypto/ecdsa" + "crypto/elliptic" + crand "crypto/rand" "fmt" "math/rand" "testing" @@ -11,7 +14,6 @@ import ( "github.com/golang/mock/gomock" "github.com/google/uuid" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-sdk-go/client" "github.com/nspcc-dev/neofs-sdk-go/netmap" "github.com/nspcc-dev/neofs-sdk-go/session" @@ -20,9 +22,6 @@ import ( ) func TestBuildPoolClientFailed(t *testing.T) { - key, err := keys.NewPrivateKey() - require.NoError(t, err) - clientBuilder := func(opts ...client.Option) (client.Client, error) { return nil, fmt.Errorf("error") } @@ -31,20 +30,17 @@ func TestBuildPoolClientFailed(t *testing.T) { pb.AddNode("peer0", 1) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, } - _, err = pb.Build(context.TODO(), opts) + _, err := pb.Build(context.TODO(), opts) require.Error(t, err) } func TestBuildPoolCreateSessionFailed(t *testing.T) { ctrl := gomock.NewController(t) - key, err := keys.NewPrivateKey() - require.NoError(t, err) - ni := &netmap.NodeInfo{} ni.SetAddresses("addr1", "addr2") @@ -59,21 +55,24 @@ func TestBuildPoolCreateSessionFailed(t *testing.T) { pb.AddNode("peer0", 1) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, } - _, err = pb.Build(context.TODO(), opts) + _, err := pb.Build(context.TODO(), opts) require.Error(t, err) } +func newPrivateKey(t *testing.T) *ecdsa.PrivateKey { + p, err := ecdsa.GenerateKey(elliptic.P256(), crand.Reader) + require.NoError(t, err) + return p +} + func TestBuildPoolOneNodeFailed(t *testing.T) { ctrl := gomock.NewController(t) ctrl2 := gomock.NewController(t) - key, err := keys.NewPrivateKey() - require.NoError(t, err) - ni := &netmap.NodeInfo{} ni.SetAddresses("addr1", "addr2") @@ -111,7 +110,7 @@ func TestBuildPoolOneNodeFailed(t *testing.T) { log, err := zap.NewProduction() require.NoError(t, err) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, ClientRebalanceInterval: 1000 * time.Millisecond, Logger: log, @@ -130,14 +129,11 @@ func TestBuildPoolOneNodeFailed(t *testing.T) { } func TestBuildPoolZeroNodes(t *testing.T) { - key, err := keys.NewPrivateKey() - require.NoError(t, err) - pb := new(Builder) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), } - _, err = pb.Build(context.TODO(), opts) + _, err := pb.Build(context.TODO(), opts) require.Error(t, err) } @@ -156,14 +152,11 @@ func TestOneNode(t *testing.T) { return mockClient, nil } - key, err := keys.NewPrivateKey() - require.NoError(t, err) - pb := new(Builder) pb.AddNode("peer0", 1) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, } @@ -194,15 +187,12 @@ func TestTwoNodes(t *testing.T) { return mockClient, nil } - key, err := keys.NewPrivateKey() - require.NoError(t, err) - pb := new(Builder) pb.AddNode("peer0", 1) pb.AddNode("peer1", 1) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, } @@ -247,15 +237,12 @@ func TestOneOfTwoFailed(t *testing.T) { return mockClient2, nil } - key, err := keys.NewPrivateKey() - require.NoError(t, err) - pb := new(Builder) pb.AddNode("peer0", 1) pb.AddNode("peer1", 9) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, ClientRebalanceInterval: 200 * time.Millisecond, } @@ -283,15 +270,12 @@ func TestTwoFailed(t *testing.T) { return mockClient, nil } - key, err := keys.NewPrivateKey() - require.NoError(t, err) - pb := new(Builder) pb.AddNode("peer0", 1) pb.AddNode("peer1", 1) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, ClientRebalanceInterval: 200 * time.Millisecond, } @@ -328,14 +312,11 @@ func TestSessionCache(t *testing.T) { return mockClient, nil } - key, err := keys.NewPrivateKey() - require.NoError(t, err) - pb := new(Builder) pb.AddNode("peer0", 1) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, ClientRebalanceInterval: 30 * time.Second, } @@ -388,16 +369,11 @@ func TestSessionCacheWithKey(t *testing.T) { return mockClient, nil } - key, err := keys.NewPrivateKey() - require.NoError(t, err) - key2, err := keys.NewPrivateKey() - require.NoError(t, err) - pb := new(Builder) pb.AddNode("peer0", 1) opts := &BuilderOptions{ - Key: &key.PrivateKey, + Key: newPrivateKey(t), clientBuilder: clientBuilder, } @@ -412,7 +388,7 @@ func TestSessionCacheWithKey(t *testing.T) { require.NoError(t, err) require.Contains(t, tokens, st) - _, err = pool.GetObject(ctx, nil, WithKey(&key2.PrivateKey)) + _, err = pool.GetObject(ctx, nil, WithKey(newPrivateKey(t))) require.NoError(t, err) require.Len(t, tokens, 2) } @@ -434,9 +410,6 @@ func TestWaitPresence(t *testing.T) { mockClient.EXPECT().EndpointInfo(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes() mockClient.EXPECT().GetContainer(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes() - key, err := keys.NewPrivateKey() - require.NoError(t, err) - cache, err := NewCache() require.NoError(t, err) @@ -446,7 +419,7 @@ func TestWaitPresence(t *testing.T) { client: mockClient, healthy: true, }}, - key: &key.PrivateKey, + key: newPrivateKey(t), cache: cache, } diff --git a/pool/sampler_test.go b/pool/sampler_test.go index bc8896c..bcff49a 100644 --- a/pool/sampler_test.go +++ b/pool/sampler_test.go @@ -6,7 +6,6 @@ import ( "math/rand" "testing" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-sdk-go/client" "github.com/nspcc-dev/neofs-sdk-go/session" "github.com/stretchr/testify/require" @@ -74,9 +73,6 @@ func TestHealthyReweight(t *testing.T) { buffer = make([]float64, len(weights)) ) - key, err := keys.NewPrivateKey() - require.NoError(t, err) - cache, err := NewCache() require.NoError(t, err) @@ -86,7 +82,7 @@ func TestHealthyReweight(t *testing.T) { {client: newNetmapMock(names[0], true), healthy: true, address: "address0"}, {client: newNetmapMock(names[1], false), healthy: true, address: "address1"}}, cache: cache, - key: &key.PrivateKey, + key: newPrivateKey(t), } // check getting first node connection before rebalance happened diff --git a/reputation/test/generate.go b/reputation/test/generate.go index e0b4bfe..1620464 100644 --- a/reputation/test/generate.go +++ b/reputation/test/generate.go @@ -1,9 +1,11 @@ package reputationtest import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" "testing" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-sdk-go/reputation" "github.com/nspcc-dev/neofs-sdk-go/util/signature" "github.com/stretchr/testify/require" @@ -12,13 +14,13 @@ import ( func GeneratePeerID() *reputation.PeerID { v := reputation.NewPeerID() - p, err := keys.NewPrivateKey() + p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { panic(err) } key := [signature.PublicKeyCompressedSize]byte{} - copy(key[:], p.Bytes()) + copy(key[:], elliptic.MarshalCompressed(p.Curve, p.X, p.Y)) v.SetPublicKey(key) return v @@ -51,9 +53,9 @@ func GenerateGlobalTrust() *reputation.GlobalTrust { func GenerateSignedGlobalTrust(t testing.TB) *reputation.GlobalTrust { gt := GenerateGlobalTrust() - priv, err := keys.NewPrivateKey() + p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, err) - require.NoError(t, gt.Sign(&priv.PrivateKey)) + require.NoError(t, gt.Sign(p)) return gt } diff --git a/session/test/token.go b/session/test/token.go index 5c63a7c..56a5f11 100644 --- a/session/test/token.go +++ b/session/test/token.go @@ -1,20 +1,22 @@ package sessiontest import ( + "crypto/ecdsa" + "crypto/elliptic" + crand "crypto/rand" "math/rand" "github.com/google/uuid" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-sdk-go/owner" "github.com/nspcc-dev/neofs-sdk-go/session" ) -var p *keys.PrivateKey +var p *ecdsa.PrivateKey func init() { var err error - p, err = keys.NewPrivateKey() + p, err = ecdsa.GenerateKey(elliptic.P256(), crand.Reader) if err != nil { panic(err) } @@ -37,7 +39,7 @@ func Generate() *session.Token { ownerID := owner.NewID() ownerID.SetNeo3Wallet(w) - keyBin := p.PublicKey().Bytes() + keyBin := elliptic.MarshalCompressed(p.PublicKey.Curve, p.PublicKey.X, p.PublicKey.Y) tok.SetID(uid) tok.SetOwnerID(ownerID) @@ -55,7 +57,7 @@ func Generate() *session.Token { func GenerateSigned() *session.Token { tok := Generate() - err := tok.Sign(&p.PrivateKey) + err := tok.Sign(p) if err != nil { panic(err) } diff --git a/token/bearer.go b/token/bearer.go index 3cec8b4..bd85e56 100644 --- a/token/bearer.go +++ b/token/bearer.go @@ -5,7 +5,6 @@ import ( "crypto/elliptic" "errors" - "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/refs" v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature" @@ -90,8 +89,14 @@ func (b *BearerToken) SignToken(key *ecdsa.PrivateKey) error { // To pass node validation it should be owner of requested container. Returns // nil if token is not signed. func (b *BearerToken) Issuer() *owner.ID { - pub, _ := keys.NewPublicKeyFromBytes(b.token.GetSignature().GetKey(), elliptic.P256()) - wallet, err := owner.NEO3WalletFromPublicKey((*ecdsa.PublicKey)(pub)) + var pub *ecdsa.PublicKey + + x, y := elliptic.UnmarshalCompressed(elliptic.P256(), b.token.GetSignature().GetKey()) + if x != nil && y != nil { + pub = &ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y} + } + + wallet, err := owner.NEO3WalletFromPublicKey(pub) if err != nil { return nil } diff --git a/token/bearer_test.go b/token/bearer_test.go index 1cd4b1e..ce6bb70 100644 --- a/token/bearer_test.go +++ b/token/bearer_test.go @@ -2,9 +2,10 @@ package token_test import ( "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" "testing" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neofs-sdk-go/eacl" "github.com/nspcc-dev/neofs-sdk-go/owner" "github.com/nspcc-dev/neofs-sdk-go/token" @@ -20,16 +21,16 @@ func TestBearerToken_Issuer(t *testing.T) { }) t.Run("signed token", func(t *testing.T) { - p, err := keys.NewPrivateKey() + p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, err) - wallet, err := owner.NEO3WalletFromPublicKey((*ecdsa.PublicKey)(p.PublicKey())) + wallet, err := owner.NEO3WalletFromPublicKey(&p.PublicKey) require.NoError(t, err) ownerID := owner.NewIDFromNeo3Wallet(wallet) bearerToken.SetEACLTable(eacl.NewTable()) - require.NoError(t, bearerToken.SignToken(&p.PrivateKey)) + require.NoError(t, bearerToken.SignToken(p)) require.True(t, ownerID.Equal(bearerToken.Issuer())) }) } diff --git a/token/test/generate.go b/token/test/generate.go index 899dba3..6597773 100644 --- a/token/test/generate.go +++ b/token/test/generate.go @@ -1,7 +1,10 @@ package tokentest import ( - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + eacltest "github.com/nspcc-dev/neofs-sdk-go/eacl/test" ownertest "github.com/nspcc-dev/neofs-sdk-go/owner/test" "github.com/nspcc-dev/neofs-sdk-go/token" @@ -26,12 +29,12 @@ func Generate() *token.BearerToken { func GenerateSigned() *token.BearerToken { tok := Generate() - p, err := keys.NewPrivateKey() + p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { panic(err) } - err = tok.SignToken(&p.PrivateKey) + err = tok.SignToken(p) if err != nil { panic(err) } diff --git a/util/signature/data.go b/util/signature/data.go index 783c66e..7c14cdd 100644 --- a/util/signature/data.go +++ b/util/signature/data.go @@ -4,9 +4,6 @@ import ( "crypto/ecdsa" "crypto/elliptic" "errors" - "fmt" - - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" ) type DataSource interface { @@ -75,8 +72,8 @@ func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySigna return err } - pub := (*keys.PublicKey)(&key.PublicKey) - handler(pub.Bytes(), sig) + b := elliptic.MarshalCompressed(key.Curve, key.X, key.Y) + handler(b, sig) return nil } @@ -96,19 +93,16 @@ func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts .. key, sig := sigSrc() - var pub *keys.PublicKey + var pub *ecdsa.PublicKey if len(key) != 0 { - pub, err = keys.NewPublicKeyFromBytes(key, elliptic.P256()) - if err != nil { - return fmt.Errorf("%w: %v", ErrInvalidPublicKey, err) + x, y := elliptic.UnmarshalCompressed(elliptic.P256(), key) + if x == nil || y == nil { + return ErrInvalidPublicKey } + pub = &ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y} } - return cfg.verifyFunc( - (*ecdsa.PublicKey)(pub), - data, - sig, - ) + return cfg.verifyFunc(pub, data, sig) } func SignData(key *ecdsa.PrivateKey, v DataWithSignature, opts ...SignOption) error { diff --git a/util/signature/options.go b/util/signature/options.go index c1cefee..2878c77 100644 --- a/util/signature/options.go +++ b/util/signature/options.go @@ -8,7 +8,7 @@ import ( "crypto/sha512" "math/big" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/rfc6979" ) var curve = elliptic.P256() @@ -77,15 +77,31 @@ func SignWithRFC6979() SignOption { } func signRFC6979(key *ecdsa.PrivateKey, msg []byte) ([]byte, error) { - p := &keys.PrivateKey{PrivateKey: *key} - return p.Sign(msg), nil + digest := sha256.Sum256(msg) + r, s := rfc6979.SignECDSA(key, digest[:], sha256.New) + return getSignatureSlice(key.Curve, r, s), nil } -func verifyRFC6979(key *ecdsa.PublicKey, msg []byte, sig []byte) error { - p := (*keys.PublicKey)(key) +func verifyRFC6979(pub *ecdsa.PublicKey, msg []byte, sig []byte) error { h := sha256.Sum256(msg) - if p.Verify(sig, h[:]) { + if pub.X == nil || pub.Y == nil || len(sig) != 64 { + return ErrInvalidSignature + } + + rBytes := new(big.Int).SetBytes(sig[0:32]) + sBytes := new(big.Int).SetBytes(sig[32:64]) + if ecdsa.Verify(pub, h[:], rBytes, sBytes) { return nil } return ErrInvalidSignature } + +func getSignatureSlice(curve elliptic.Curve, r, s *big.Int) []byte { + params := curve.Params() + curveOrderByteSize := params.P.BitLen() / 8 + signature := make([]byte, curveOrderByteSize*2) + _ = r.FillBytes(signature[:curveOrderByteSize]) + _ = s.FillBytes(signature[curveOrderByteSize:]) + + return signature +}