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 }