lbry.go/schema/stake/sign.go
2021-10-20 12:23:55 -04:00

99 lines
2.4 KiB
Go

package stake
import (
"crypto/sha256"
"encoding/hex"
"github.com/lbryio/lbry.go/v3/schema/address"
"github.com/lbryio/lbry.go/v3/schema/keys"
"github.com/lbryio/lbcd/btcec"
"github.com/cockroachdb/errors"
)
func Sign(privKey btcec.PrivateKey, channel Helper, claim Helper, k string) (*keys.Signature, error) {
if channel.Claim.GetChannel() == nil {
return nil, errors.WithStack(errors.New("claim as channel is not of type channel"))
}
if claim.LegacyClaim != nil {
return claim.signV1(privKey, channel, k)
}
return claim.sign(privKey, channel, k)
}
func (c *Helper) sign(privKey btcec.PrivateKey, channel Helper, firstInputTxID string) (*keys.Signature, error) {
txidBytes, err := hex.DecodeString(firstInputTxID)
if err != nil {
return nil, errors.WithStack(err)
}
metadataBytes, err := c.serialized()
if err != nil {
return nil, err
}
var digest []byte
digest = append(digest, txidBytes...)
digest = append(digest, c.ClaimID...)
digest = append(digest, metadataBytes...)
hash := sha256.Sum256(digest)
hashBytes := make([]byte, len(hash))
for i, b := range hash {
hashBytes[i] = b
}
sig, err := privKey.Sign(hashBytes)
if err != nil {
return nil, errors.WithStack(err)
}
return &keys.Signature{*sig}, nil
}
func (c *Helper) signV1(privKey btcec.PrivateKey, channel Helper, claimAddress string) (*keys.Signature, error) {
metadataBytes, err := c.serializedNoSignature()
if err != nil {
return nil, errors.WithStack(err)
}
addressBytes, err := address.DecodeAddress(claimAddress, "lbrycrd_main")
if err != nil {
return nil, errors.WithMessage(err, "V1 signing requires claim address and the decode failed")
}
var digest []byte
address := make([]byte, len(addressBytes))
for i, b := range addressBytes {
address[i] = b
}
digest = append(digest, address...)
digest = append(digest, metadataBytes...)
digest = append(digest, channel.ClaimID...)
hash := sha256.Sum256(digest)
hashBytes := make([]byte, len(hash))
for i, b := range hash {
hashBytes[i] = b
}
sig, err := privKey.Sign(hashBytes)
if err != nil {
return nil, errors.WithStack(err)
}
return &keys.Signature{Signature: *sig}, nil
}
// rev reverses a byte slice. useful for switching endian-ness
func reverseBytes(b []byte) []byte {
r := make([]byte, len(b))
for left, right := 0, len(b)-1; left < right; left, right = left+1, right-1 {
r[left], r[right] = b[right], b[left]
}
return r
}