git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/crypto/ecdsa/wallet_connect.go (about)

     1  package frostfsecdsa
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"crypto/elliptic"
     6  	"encoding/base64"
     7  	"fmt"
     8  
     9  	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/signature/walletconnect"
    10  	frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
    11  	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
    12  )
    13  
    14  // SignerWalletConnect is similar to SignerRFC6979 with 2 changes:
    15  // 1. The data is base64 encoded before signing/verifying.
    16  // 2. The signature is a concatenation of the signature itself and 16-byte salt.
    17  //
    18  // Instances MUST be initialized from ecdsa.PrivateKey using type conversion.
    19  type SignerWalletConnect ecdsa.PrivateKey
    20  
    21  // Scheme returns frostfscrypto.ECDSA_WALLETCONNECT.
    22  // Implements frostfscrypto.Signer.
    23  func (x SignerWalletConnect) Scheme() frostfscrypto.Scheme {
    24  	return frostfscrypto.ECDSA_WALLETCONNECT
    25  }
    26  
    27  // Sign signs data using ECDSA algorithm with SHA-512 hashing.
    28  // Implements frostfscrypto.Signer.
    29  func (x SignerWalletConnect) Sign(data []byte) ([]byte, error) {
    30  	b64 := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
    31  	base64.StdEncoding.Encode(b64, data)
    32  	return walletconnect.Sign((*ecdsa.PrivateKey)(&x), b64)
    33  }
    34  
    35  // Public initializes PublicKey and returns it as frostfscrypto.PublicKey.
    36  // Implements frostfscrypto.Signer.
    37  func (x SignerWalletConnect) Public() frostfscrypto.PublicKey {
    38  	return (*PublicKeyWalletConnect)(&x.PublicKey)
    39  }
    40  
    41  // PublicKeyWalletConnect is a wrapper over ecdsa.PublicKey used for FrostFS needs.
    42  // Provides frostfscrypto.PublicKey interface.
    43  //
    44  // Instances MUST be initialized from ecdsa.PublicKey using type conversion.
    45  type PublicKeyWalletConnect ecdsa.PublicKey
    46  
    47  // MaxEncodedSize returns size of the compressed ECDSA public key.
    48  func (x PublicKeyWalletConnect) MaxEncodedSize() int {
    49  	return 33
    50  }
    51  
    52  // Encode encodes ECDSA public key in compressed form into buf.
    53  // Uses exactly MaxEncodedSize bytes of the buf.
    54  //
    55  // Encode panics if buf length is less than MaxEncodedSize.
    56  //
    57  // See also Decode.
    58  func (x PublicKeyWalletConnect) Encode(buf []byte) int {
    59  	if len(buf) < 33 {
    60  		panic(fmt.Sprintf("too short buffer %d", len(buf)))
    61  	}
    62  
    63  	return copy(buf, (*keys.PublicKey)(&x).Bytes())
    64  }
    65  
    66  // Decode decodes compressed binary representation of the PublicKeyWalletConnect.
    67  //
    68  // See also Encode.
    69  func (x *PublicKeyWalletConnect) Decode(data []byte) error {
    70  	pub, err := keys.NewPublicKeyFromBytes(data, elliptic.P256())
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	*x = (PublicKeyWalletConnect)(*pub)
    76  
    77  	return nil
    78  }
    79  
    80  // Verify verifies data signature calculated by ECDSA algorithm with SHA-512 hashing.
    81  func (x PublicKeyWalletConnect) Verify(data, signature []byte) bool {
    82  	b64 := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
    83  	base64.StdEncoding.Encode(b64, data)
    84  	return walletconnect.Verify((*ecdsa.PublicKey)(&x), b64, signature)
    85  }