github.com/decred/dcrlnd@v0.7.6/lntest/mock/signer.go (about)

     1  package mock
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/decred/dcrd/chaincfg/chainhash"
     7  	"github.com/decred/dcrd/dcrec"
     8  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
     9  	"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
    10  	"github.com/decred/dcrd/txscript/v4/sign"
    11  	"github.com/decred/dcrd/wire"
    12  
    13  	"github.com/decred/dcrlnd/input"
    14  	"github.com/decred/dcrlnd/keychain"
    15  )
    16  
    17  // DummySignature is a dummy Signature implementation.
    18  type DummySignature struct{}
    19  
    20  // Serialize returns an empty byte slice.
    21  func (d *DummySignature) Serialize() []byte {
    22  	return []byte{}
    23  }
    24  
    25  // Verify always returns true.
    26  func (d *DummySignature) Verify(_ []byte, _ *secp256k1.PublicKey) bool {
    27  	return true
    28  }
    29  
    30  // DummySigner is an implementation of the Signer interface that returns
    31  // dummy values when called.
    32  type DummySigner struct{}
    33  
    34  // SignOutputRaw returns a dummy signature.
    35  func (d *DummySigner) SignOutputRaw(tx *wire.MsgTx,
    36  	signDesc *input.SignDescriptor) (input.Signature, error) {
    37  
    38  	return &DummySignature{}, nil
    39  }
    40  
    41  // ComputeInputScript returns nil for both values.
    42  func (d *DummySigner) ComputeInputScript(tx *wire.MsgTx,
    43  	signDesc *input.SignDescriptor) (*input.Script, error) {
    44  
    45  	return &input.Script{}, nil
    46  }
    47  
    48  // SingleSigner is an implementation of the Signer interface that signs
    49  // everything with a single private key.
    50  type SingleSigner struct {
    51  	Privkey *secp256k1.PrivateKey
    52  	KeyLoc  keychain.KeyLocator
    53  }
    54  
    55  // SignOutputRaw generates a signature for the passed transaction using the
    56  // stored private key.
    57  func (s *SingleSigner) SignOutputRaw(tx *wire.MsgTx,
    58  	signDesc *input.SignDescriptor) (input.Signature, error) {
    59  
    60  	witnessScript := signDesc.WitnessScript
    61  	privKey := s.Privkey
    62  
    63  	if !privKey.PubKey().IsEqual(signDesc.KeyDesc.PubKey) {
    64  		return nil, fmt.Errorf("incorrect key passed")
    65  	}
    66  
    67  	switch {
    68  	case signDesc.SingleTweak != nil:
    69  		privKey = input.TweakPrivKey(privKey,
    70  			signDesc.SingleTweak)
    71  	case signDesc.DoubleTweak != nil:
    72  		privKey = input.DeriveRevocationPrivKey(privKey,
    73  			signDesc.DoubleTweak)
    74  	}
    75  
    76  	sig, err := sign.RawTxInSignature(tx,
    77  		signDesc.InputIndex, witnessScript, signDesc.HashType,
    78  		privKey.Serialize(), dcrec.STEcdsaSecp256k1)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	return ecdsa.ParseDERSignature(sig[:len(sig)-1])
    84  }
    85  
    86  // ComputeInputScript computes an input script with the stored private key
    87  // given a transaction and a SignDescriptor.
    88  func (s *SingleSigner) ComputeInputScript(tx *wire.MsgTx,
    89  	signDesc *input.SignDescriptor) (*input.Script, error) {
    90  
    91  	privKey := s.Privkey
    92  
    93  	switch {
    94  	case signDesc.SingleTweak != nil:
    95  		privKey = input.TweakPrivKey(privKey,
    96  			signDesc.SingleTweak)
    97  	case signDesc.DoubleTweak != nil:
    98  		privKey = input.DeriveRevocationPrivKey(privKey,
    99  			signDesc.DoubleTweak)
   100  	}
   101  
   102  	witnessScript, err := sign.SignatureScript(tx,
   103  		signDesc.InputIndex, signDesc.Output.PkScript,
   104  		signDesc.HashType, privKey.Serialize(), dcrec.STEcdsaSecp256k1, true)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  
   109  	return &input.Script{
   110  		SigScript: witnessScript,
   111  	}, nil
   112  }
   113  
   114  // SignMessage takes a public key and a message and only signs the message
   115  // with the stored private key if the public key matches the private key.
   116  func (s *SingleSigner) SignMessage(keyLoc keychain.KeyLocator,
   117  	msg []byte, doubleHash bool) (*ecdsa.Signature, error) {
   118  
   119  	mockKeyLoc := s.KeyLoc
   120  	if s.KeyLoc.IsEmpty() {
   121  		mockKeyLoc = keyLoc
   122  	}
   123  
   124  	if keyLoc != mockKeyLoc {
   125  		return nil, fmt.Errorf("unknown public key")
   126  	}
   127  
   128  	var digest []byte
   129  	if doubleHash {
   130  		return nil, fmt.Errorf("dcrlnd does not do doubleHash signing")
   131  	} else {
   132  		digest = chainhash.HashB(msg)
   133  	}
   134  	sign := ecdsa.Sign(s.Privkey, digest)
   135  	return sign, nil
   136  }