2022-12-13 14:36:35 +00:00
|
|
|
package frostfsecdsa
|
2022-03-10 12:25:14 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/elliptic"
|
|
|
|
"encoding/base64"
|
|
|
|
"fmt"
|
|
|
|
|
2024-10-07 14:20:25 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/util/signature/walletconnect"
|
2023-03-07 11:20:03 +00:00
|
|
|
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
2022-03-10 12:25:14 +00:00
|
|
|
"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
|
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
// Scheme returns frostfscrypto.ECDSA_WALLETCONNECT.
|
|
|
|
// Implements frostfscrypto.Signer.
|
|
|
|
func (x SignerWalletConnect) Scheme() frostfscrypto.Scheme {
|
|
|
|
return frostfscrypto.ECDSA_WALLETCONNECT
|
2022-03-10 12:25:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sign signs data using ECDSA algorithm with SHA-512 hashing.
|
2022-12-13 14:36:35 +00:00
|
|
|
// Implements frostfscrypto.Signer.
|
2022-03-10 12:25:14 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
// Public initializes PublicKey and returns it as frostfscrypto.PublicKey.
|
|
|
|
// Implements frostfscrypto.Signer.
|
|
|
|
func (x SignerWalletConnect) Public() frostfscrypto.PublicKey {
|
2022-03-10 12:25:14 +00:00
|
|
|
return (*PublicKeyWalletConnect)(&x.PublicKey)
|
|
|
|
}
|
|
|
|
|
2022-12-29 10:46:18 +00:00
|
|
|
// PublicKeyWalletConnect is a wrapper over ecdsa.PublicKey used for FrostFS needs.
|
2022-12-13 14:36:35 +00:00
|
|
|
// Provides frostfscrypto.PublicKey interface.
|
2022-03-10 12:25:14 +00:00
|
|
|
//
|
|
|
|
// 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)
|
|
|
|
}
|