2022-12-13 14:36:35 +00:00
|
|
|
package frostfsecdsa
|
2022-04-05 11:13:34 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/elliptic"
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/sha512"
|
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
frostfscrypto "github.com/TrueCloudLab/frostfs-sdk-go/crypto"
|
2022-04-05 11:13:34 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
|
|
)
|
|
|
|
|
2022-04-19 08:11:29 +00:00
|
|
|
// Signer wraps ecdsa.PrivateKey and represents signer based on ECDSA with
|
2022-12-13 14:36:35 +00:00
|
|
|
// SHA-512 hashing. Provides frostfscrypto.Signer interface.
|
2022-04-05 11:13:34 +00:00
|
|
|
//
|
2022-04-19 08:11:29 +00:00
|
|
|
// Instances MUST be initialized from ecdsa.PrivateKey using type conversion.
|
|
|
|
type Signer ecdsa.PrivateKey
|
2022-04-05 11:13:34 +00:00
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
// Scheme returns frostfscrypto.ECDSA_SHA512.
|
|
|
|
// Implements frostfscrypto.Signer.
|
|
|
|
func (x Signer) Scheme() frostfscrypto.Scheme {
|
|
|
|
return frostfscrypto.ECDSA_SHA512
|
2022-04-05 11:13:34 +00:00
|
|
|
}
|
|
|
|
|
2022-04-19 08:11:29 +00:00
|
|
|
// Sign signs data using ECDSA algorithm with SHA-512 hashing.
|
2022-12-13 14:36:35 +00:00
|
|
|
// Implements frostfscrypto.Signer.
|
2022-04-05 11:13:34 +00:00
|
|
|
func (x Signer) Sign(data []byte) ([]byte, error) {
|
|
|
|
h := sha512.Sum512(data)
|
2022-04-19 08:11:29 +00:00
|
|
|
r, s, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(&x), h[:])
|
2022-04-05 11:13:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-08-18 10:10:18 +00:00
|
|
|
params := elliptic.P256().Params()
|
|
|
|
curveOrderByteSize := params.P.BitLen() / 8
|
|
|
|
|
|
|
|
buf := make([]byte, 1+curveOrderByteSize*2)
|
|
|
|
buf[0] = 4
|
|
|
|
|
|
|
|
_ = r.FillBytes(buf[1 : 1+curveOrderByteSize])
|
|
|
|
_ = s.FillBytes(buf[1+curveOrderByteSize:])
|
|
|
|
|
|
|
|
return buf, nil
|
2022-04-05 11:13:34 +00:00
|
|
|
}
|
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
// Public initializes PublicKey and returns it as frostfscrypto.PublicKey.
|
|
|
|
// Implements frostfscrypto.Signer.
|
|
|
|
func (x Signer) Public() frostfscrypto.PublicKey {
|
2022-04-19 08:11:29 +00:00
|
|
|
return (*PublicKey)(&x.PublicKey)
|
|
|
|
}
|
2022-04-05 11:13:34 +00:00
|
|
|
|
2022-04-19 08:11:29 +00:00
|
|
|
// SignerRFC6979 wraps ecdsa.PrivateKey and represents signer based on deterministic
|
2022-12-13 14:36:35 +00:00
|
|
|
// ECDSA with SHA-256 hashing (RFC 6979). Provides frostfscrypto.Signer interface.
|
2022-04-19 08:11:29 +00:00
|
|
|
//
|
|
|
|
// Instances SHOULD be initialized from ecdsa.PrivateKey using type conversion.
|
|
|
|
type SignerRFC6979 ecdsa.PrivateKey
|
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
// Scheme returns frostfscrypto.ECDSA_DETERMINISTIC_SHA256.
|
|
|
|
// Implements frostfscrypto.Signer.
|
|
|
|
func (x SignerRFC6979) Scheme() frostfscrypto.Scheme {
|
|
|
|
return frostfscrypto.ECDSA_DETERMINISTIC_SHA256
|
2022-04-19 08:11:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sign signs data using deterministic ECDSA algorithm with SHA-256 hashing.
|
2022-12-13 14:36:35 +00:00
|
|
|
// Implements frostfscrypto.Signer.
|
2022-04-19 08:11:29 +00:00
|
|
|
//
|
|
|
|
// See also RFC 6979.
|
|
|
|
func (x SignerRFC6979) Sign(data []byte) ([]byte, error) {
|
|
|
|
p := keys.PrivateKey{PrivateKey: (ecdsa.PrivateKey)(x)}
|
|
|
|
return p.Sign(data), nil
|
|
|
|
}
|
2022-04-05 11:13:34 +00:00
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
// Public initializes PublicKeyRFC6979 and returns it as frostfscrypto.PublicKey.
|
|
|
|
// Implements frostfscrypto.Signer.
|
|
|
|
func (x SignerRFC6979) Public() frostfscrypto.PublicKey {
|
2022-04-19 08:11:29 +00:00
|
|
|
return (*PublicKeyRFC6979)(&x.PublicKey)
|
2022-04-05 11:13:34 +00:00
|
|
|
}
|