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

     1  package frostfsecdsa
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"crypto/elliptic"
     6  	"crypto/rand"
     7  	"crypto/sha512"
     8  
     9  	frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
    10  	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
    11  )
    12  
    13  // Signer wraps ecdsa.PrivateKey and represents signer based on ECDSA with
    14  // SHA-512 hashing. Provides frostfscrypto.Signer interface.
    15  //
    16  // Instances MUST be initialized from ecdsa.PrivateKey using type conversion.
    17  type Signer ecdsa.PrivateKey
    18  
    19  // Scheme returns frostfscrypto.ECDSA_SHA512.
    20  // Implements frostfscrypto.Signer.
    21  func (x Signer) Scheme() frostfscrypto.Scheme {
    22  	return frostfscrypto.ECDSA_SHA512
    23  }
    24  
    25  // Sign signs data using ECDSA algorithm with SHA-512 hashing.
    26  // Implements frostfscrypto.Signer.
    27  func (x Signer) Sign(data []byte) ([]byte, error) {
    28  	h := sha512.Sum512(data)
    29  	r, s, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(&x), h[:])
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	params := elliptic.P256().Params()
    35  	curveOrderByteSize := params.P.BitLen() / 8
    36  
    37  	buf := make([]byte, 1+curveOrderByteSize*2)
    38  	buf[0] = 4
    39  
    40  	_ = r.FillBytes(buf[1 : 1+curveOrderByteSize])
    41  	_ = s.FillBytes(buf[1+curveOrderByteSize:])
    42  
    43  	return buf, nil
    44  }
    45  
    46  // Public initializes PublicKey and returns it as frostfscrypto.PublicKey.
    47  // Implements frostfscrypto.Signer.
    48  func (x Signer) Public() frostfscrypto.PublicKey {
    49  	return (*PublicKey)(&x.PublicKey)
    50  }
    51  
    52  // SignerRFC6979 wraps ecdsa.PrivateKey and represents signer based on deterministic
    53  // ECDSA with SHA-256 hashing (RFC 6979). Provides frostfscrypto.Signer interface.
    54  //
    55  // Instances SHOULD be initialized from ecdsa.PrivateKey using type conversion.
    56  type SignerRFC6979 ecdsa.PrivateKey
    57  
    58  // Scheme returns frostfscrypto.ECDSA_DETERMINISTIC_SHA256.
    59  // Implements frostfscrypto.Signer.
    60  func (x SignerRFC6979) Scheme() frostfscrypto.Scheme {
    61  	return frostfscrypto.ECDSA_DETERMINISTIC_SHA256
    62  }
    63  
    64  // Sign signs data using deterministic ECDSA algorithm with SHA-256 hashing.
    65  // Implements frostfscrypto.Signer.
    66  //
    67  // See also RFC 6979.
    68  func (x SignerRFC6979) Sign(data []byte) ([]byte, error) {
    69  	p := keys.PrivateKey{PrivateKey: (ecdsa.PrivateKey)(x)}
    70  	return p.Sign(data), nil
    71  }
    72  
    73  // Public initializes PublicKeyRFC6979 and returns it as frostfscrypto.PublicKey.
    74  // Implements frostfscrypto.Signer.
    75  func (x SignerRFC6979) Public() frostfscrypto.PublicKey {
    76  	return (*PublicKeyRFC6979)(&x.PublicKey)
    77  }