package frostfsecdsa import ( "crypto/ecdsa" "crypto/elliptic" "encoding/base64" "fmt" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/signature/walletconnect" frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" ) // 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 frostfscrypto.ECDSA_WALLETCONNECT. // Implements frostfscrypto.Signer. func (x SignerWalletConnect) Scheme() frostfscrypto.Scheme { return frostfscrypto.ECDSA_WALLETCONNECT } // Sign signs data using ECDSA algorithm with SHA-512 hashing. // Implements frostfscrypto.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 frostfscrypto.PublicKey. // Implements frostfscrypto.Signer. func (x SignerWalletConnect) Public() frostfscrypto.PublicKey { return (*PublicKeyWalletConnect)(&x.PublicKey) } // PublicKeyWalletConnect is a wrapper over ecdsa.PublicKey used for FrostFS needs. // Provides frostfscrypto.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) }