frostfs-crypto/wif.go
alexvanin 8fa65a0afc Use consistent parameter names for Sign and Verify functions
It may be misleading when verify function takes signature as a hash
parameter. This commit suggested to use rfc6979 original naming
for the parameters:
- `msg` as the message to sign,
- `sig` as the signature of message.
All hashing operations are encapsulated inside of the Sign
and Verify functions.

Also there are comment fixes and re-usage of `hashBytes()` in rfc6979.
2019-11-12 14:52:23 +03:00

62 lines
1.6 KiB
Go

package crypto
import (
"bytes"
"crypto/ecdsa"
"crypto/sha256"
"github.com/mr-tron/base58"
"github.com/nspcc-dev/neofs-crypto/internal"
"github.com/pkg/errors"
)
const (
// WIFLength constant length of WIF string.
WIFLength = 38
// ErrBadWIF when passed WIF-string could not be decoded from base58.
ErrBadWIF = internal.Error("bad wif")
// ErrBadChecksum when passed WIF-string could not be verified
// by last 4 bytes signature.
ErrBadChecksum = internal.Error("bad checksum")
// ErrEmptyPrivateKey when PK passed into WIFEncode method is nil.
ErrEmptyPrivateKey = internal.Error("empty private key")
)
func wifCheckSum(data []byte) []byte {
sum := sha256.Sum256(data)
sum = sha256.Sum256(sum[:])
return sum[:4]
}
// WIFEncode encodes the given private key into a WIF string.
func WIFEncode(key *ecdsa.PrivateKey) (string, error) {
if key == nil || key.D == nil {
return "", ErrEmptyPrivateKey
}
data := make([]byte, WIFLength)
data[0] = 0x80
data[33] = 0x01
copy(data[1:33], key.D.Bytes())
copy(data[34:], wifCheckSum(data[:34]))
return base58.Encode(data), nil
}
// WIFDecode decoded the given WIF string into a private key.
func WIFDecode(wif string) (*ecdsa.PrivateKey, error) {
data, err := base58.Decode(wif)
if err != nil {
return nil, errors.Wrap(ErrBadWIF, err.Error())
} else if actual := len(data); actual != WIFLength {
return nil, errors.Wrapf(ErrBadWIF, "expect: %d, actual: %d", WIFLength, actual)
} else if sum := wifCheckSum(data[:34]); !bytes.Equal(data[34:], sum) {
return nil, ErrBadChecksum
}
return UnmarshalPrivateKey(data[1:33])
}