github.com/decred/dcrlnd@v0.7.6/watchtower/wtmock/signer.go (about) 1 package wtmock 2 3 import ( 4 "sync" 5 6 "github.com/decred/dcrd/dcrec" 7 "github.com/decred/dcrd/dcrec/secp256k1/v4" 8 "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" 9 "github.com/decred/dcrd/txscript/v4/sign" 10 "github.com/decred/dcrd/wire" 11 "github.com/decred/dcrlnd/input" 12 "github.com/decred/dcrlnd/keychain" 13 ) 14 15 // MockSigner is an input.Signer that allows one to add arbitrary private keys 16 // and sign messages by passing the assigned keychain.KeyLocator. 17 type MockSigner struct { 18 mu sync.Mutex 19 20 index uint32 21 keys map[keychain.KeyLocator]*secp256k1.PrivateKey 22 } 23 24 // NewMockSigner returns a fresh MockSigner. 25 func NewMockSigner() *MockSigner { 26 return &MockSigner{ 27 keys: make(map[keychain.KeyLocator]*secp256k1.PrivateKey), 28 } 29 } 30 31 // SignOutputRaw signs an input on the passed transaction using the input index 32 // in the sign descriptor. The returned signature is the raw DER-encoded 33 // signature without the signhash flag. 34 func (s *MockSigner) SignOutputRaw(tx *wire.MsgTx, 35 signDesc *input.SignDescriptor) (input.Signature, error) { 36 s.mu.Lock() 37 defer s.mu.Unlock() 38 39 witnessScript := signDesc.WitnessScript 40 41 privKey, ok := s.keys[signDesc.KeyDesc.KeyLocator] 42 if !ok { 43 panic("cannot sign w/ unknown key") 44 } 45 46 sig, err := sign.RawTxInSignature( 47 tx, signDesc.InputIndex, 48 witnessScript, signDesc.HashType, privKey.Serialize(), 49 dcrec.STEcdsaSecp256k1, 50 ) 51 if err != nil { 52 return nil, err 53 } 54 55 return ecdsa.ParseDERSignature(sig[:len(sig)-1]) 56 } 57 58 // ComputeInputScript is not implemented. 59 func (s *MockSigner) ComputeInputScript(tx *wire.MsgTx, 60 signDesc *input.SignDescriptor) (*input.Script, error) { 61 panic("not implemented") 62 } 63 64 // AddPrivKey records the passed privKey in the MockSigner's registry of keys it 65 // can sign with in the future. A unique key locator is returned, allowing the 66 // caller to sign with this key when presented via an input.SignDescriptor. 67 func (s *MockSigner) AddPrivKey(privKey *secp256k1.PrivateKey) keychain.KeyLocator { 68 s.mu.Lock() 69 defer s.mu.Unlock() 70 71 keyLoc := keychain.KeyLocator{ 72 Index: s.index, 73 } 74 s.index++ 75 76 s.keys[keyLoc] = privKey 77 78 return keyLoc 79 } 80 81 // Compile-time constraint ensuring the MockSigner implements the input.Signer 82 // interface. 83 var _ input.Signer = (*MockSigner)(nil)