[#274] crypto: Add WalletConnect API support

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-03-10 15:25:14 +03:00 committed by fyrchik
parent 721df386c5
commit 596f43a540
6 changed files with 97 additions and 4 deletions

View file

@ -28,6 +28,9 @@ func TestSignature(t *testing.T) {
func() neofscrypto.Signer { func() neofscrypto.Signer {
return neofsecdsa.SignerRFC6979(k.PrivateKey) return neofsecdsa.SignerRFC6979(k.PrivateKey)
}, },
func() neofscrypto.Signer {
return neofsecdsa.SignerWalletConnect(k.PrivateKey)
},
} { } {
signer := f() signer := f()
@ -39,6 +42,6 @@ func TestSignature(t *testing.T) {
s.ReadFromV2(m) s.ReadFromV2(m)
valid := s.Verify(data) valid := s.Verify(data)
require.True(t, valid) require.True(t, valid, "type %T", signer)
} }
} }

View file

@ -10,4 +10,8 @@ func init() {
neofscrypto.RegisterScheme(neofscrypto.ECDSA_DETERMINISTIC_SHA256, func() neofscrypto.PublicKey { neofscrypto.RegisterScheme(neofscrypto.ECDSA_DETERMINISTIC_SHA256, func() neofscrypto.PublicKey {
return new(PublicKeyRFC6979) return new(PublicKeyRFC6979)
}) })
neofscrypto.RegisterScheme(neofscrypto.ECDSA_WALLETCONNECT, func() neofscrypto.PublicKey {
return new(PublicKeyWalletConnect)
})
} }

View file

@ -0,0 +1,85 @@
package neofsecdsa
import (
"crypto/ecdsa"
"crypto/elliptic"
"encoding/base64"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-api-go/v2/util/signature/walletconnect"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
)
// SignerWalletConnect is similar to SignerRFC6979 with 2 changes:
// 1. The data is base64 encoded before signing/verifying.
// 2. The signature is a concatenation of the signature itself and 16-byte salt.
//
// Instances MUST be initialized from ecdsa.PrivateKey using type conversion.
type SignerWalletConnect ecdsa.PrivateKey
// Scheme returns neofscrypto.ECDSA_WALLETCONNECT.
// Implements neofscrypto.Signer.
func (x SignerWalletConnect) Scheme() neofscrypto.Scheme {
return neofscrypto.ECDSA_WALLETCONNECT
}
// Sign signs data using ECDSA algorithm with SHA-512 hashing.
// Implements neofscrypto.Signer.
func (x SignerWalletConnect) Sign(data []byte) ([]byte, error) {
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
base64.StdEncoding.Encode(b64, data)
return walletconnect.Sign((*ecdsa.PrivateKey)(&x), b64)
}
// Public initializes PublicKey and returns it as neofscrypto.PublicKey.
// Implements neofscrypto.Signer.
func (x SignerWalletConnect) Public() neofscrypto.PublicKey {
return (*PublicKeyWalletConnect)(&x.PublicKey)
}
// PublicKeyWalletConnect is a wrapper over ecdsa.PublicKey used for NeoFS needs.
// Provides neofscrypto.PublicKey interface.
//
// Instances MUST be initialized from ecdsa.PublicKey using type conversion.
type PublicKeyWalletConnect ecdsa.PublicKey
// MaxEncodedSize returns size of the compressed ECDSA public key.
func (x PublicKeyWalletConnect) MaxEncodedSize() int {
return 33
}
// Encode encodes ECDSA public key in compressed form into buf.
// Uses exactly MaxEncodedSize bytes of the buf.
//
// Encode panics if buf length is less than MaxEncodedSize.
//
// See also Decode.
func (x PublicKeyWalletConnect) Encode(buf []byte) int {
if len(buf) < 33 {
panic(fmt.Sprintf("too short buffer %d", len(buf)))
}
return copy(buf, (*keys.PublicKey)(&x).Bytes())
}
// Decode decodes compressed binary representation of the PublicKeyWalletConnect.
//
// See also Encode.
func (x *PublicKeyWalletConnect) Decode(data []byte) error {
pub, err := keys.NewPublicKeyFromBytes(data, elliptic.P256())
if err != nil {
return err
}
*x = (PublicKeyWalletConnect)(*pub)
return nil
}
// Verify verifies data signature calculated by ECDSA algorithm with SHA-512 hashing.
func (x PublicKeyWalletConnect) Verify(data, signature []byte) bool {
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
base64.StdEncoding.Encode(b64, data)
return walletconnect.Verify((*ecdsa.PublicKey)(&x), b64, signature)
}

View file

@ -17,6 +17,7 @@ const (
ECDSA_SHA512 // ECDSA with SHA-512 hashing (FIPS 186-3) ECDSA_SHA512 // ECDSA with SHA-512 hashing (FIPS 186-3)
ECDSA_DETERMINISTIC_SHA256 // Deterministic ECDSA with SHA-256 hashing (RFC 6979) ECDSA_DETERMINISTIC_SHA256 // Deterministic ECDSA with SHA-256 hashing (RFC 6979)
ECDSA_WALLETCONNECT // Wallet Connect signature scheme
) )
// String implements fmt.Stringer. // String implements fmt.Stringer.

2
go.mod
View file

@ -10,7 +10,7 @@ require (
github.com/mr-tron/base58 v1.2.0 github.com/mr-tron/base58 v1.2.0
github.com/nspcc-dev/hrw v1.0.9 github.com/nspcc-dev/hrw v1.0.9
github.com/nspcc-dev/neo-go v0.98.2 github.com/nspcc-dev/neo-go v0.98.2
github.com/nspcc-dev/neofs-api-go/v2 v2.12.2 github.com/nspcc-dev/neofs-api-go/v2 v2.12.3-0.20220621170933-dd233c3fbc84
github.com/nspcc-dev/neofs-contract v0.15.1 github.com/nspcc-dev/neofs-contract v0.15.1
github.com/nspcc-dev/tzhash v1.5.2 github.com/nspcc-dev/tzhash v1.5.2
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0

4
go.sum
View file

@ -182,8 +182,8 @@ github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321113211-526c423a6152 h1:JK
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321113211-526c423a6152/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y= github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321113211-526c423a6152/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs= github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs= github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
github.com/nspcc-dev/neofs-api-go/v2 v2.12.2 h1:ifV/c0bW1TPiEKZlNqhfZl8lzX0f6FokjYUaze/hlBk= github.com/nspcc-dev/neofs-api-go/v2 v2.12.3-0.20220621170933-dd233c3fbc84 h1:4tZSQ2DL/oatbte35+vDSt2nYpQ0G2et1DrpxodGwRM=
github.com/nspcc-dev/neofs-api-go/v2 v2.12.2/go.mod h1:73j09Xa7I2zQbM3HCvAHnDHPYiiWnEHa1d6Z6RDMBLU= github.com/nspcc-dev/neofs-api-go/v2 v2.12.3-0.20220621170933-dd233c3fbc84/go.mod h1:73j09Xa7I2zQbM3HCvAHnDHPYiiWnEHa1d6Z6RDMBLU=
github.com/nspcc-dev/neofs-contract v0.15.1 h1:1r27t4SGKF7W1PRPOIfircEXHvALThNYNagT+SIabcA= github.com/nspcc-dev/neofs-contract v0.15.1 h1:1r27t4SGKF7W1PRPOIfircEXHvALThNYNagT+SIabcA=
github.com/nspcc-dev/neofs-contract v0.15.1/go.mod h1:kxO5ZTqdzFnRM5RMvM+Fhd+3GGrJo6AmG2ZyA9OCqqQ= github.com/nspcc-dev/neofs-contract v0.15.1/go.mod h1:kxO5ZTqdzFnRM5RMvM+Fhd+3GGrJo6AmG2ZyA9OCqqQ=
github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA= github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=