1 // Copyright (c) 2013-2017 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
10 "github.com/btcsuite/btcd/chaincfg/chainhash"
11 "github.com/btcsuite/btcd/wire"
14 // TestBadPC sets the pc to a deliberately bad result then confirms that Step()
15 // and Disasm fail correctly.
16 func TestBadPC(t *testing.T) {
26 // tx with almost empty scripts.
31 PreviousOutPoint: wire.OutPoint{
32 Hash: chainhash.Hash([32]byte{
33 0xc9, 0x97, 0xa5, 0xe5,
34 0x6e, 0x10, 0x41, 0x02,
35 0xfa, 0x20, 0x9c, 0x6a,
36 0x85, 0x2d, 0xd9, 0x06,
37 0x60, 0xa2, 0x0b, 0x2d,
38 0x9c, 0x35, 0x24, 0x23,
39 0xed, 0xce, 0x25, 0x85,
40 0x7f, 0xcd, 0x37, 0x04,
44 SignatureScript: mustParseShortForm("NOP"),
48 TxOut: []*wire.TxOut{{
54 pkScript := mustParseShortForm("NOP")
56 for _, test := range tests {
57 vm, err := NewEngine(pkScript, tx, 0, 0, nil, nil, -1)
59 t.Errorf("Failed to create script: %v", err)
62 // set to after all scripts
63 vm.scriptIdx = test.script
64 vm.scriptOff = test.off
68 t.Errorf("Step with invalid pc (%v) succeeds!", test)
72 _, err = vm.DisasmPC()
74 t.Errorf("DisasmPC with invalid pc (%v) succeeds!",
80 // TestCheckErrorCondition tests the execute early test in CheckErrorCondition()
81 // since most code paths are tested elsewhere.
82 func TestCheckErrorCondition(t *testing.T) {
85 // tx with almost empty scripts.
89 PreviousOutPoint: wire.OutPoint{
90 Hash: chainhash.Hash([32]byte{
91 0xc9, 0x97, 0xa5, 0xe5,
92 0x6e, 0x10, 0x41, 0x02,
93 0xfa, 0x20, 0x9c, 0x6a,
94 0x85, 0x2d, 0xd9, 0x06,
95 0x60, 0xa2, 0x0b, 0x2d,
96 0x9c, 0x35, 0x24, 0x23,
97 0xed, 0xce, 0x25, 0x85,
98 0x7f, 0xcd, 0x37, 0x04,
102 SignatureScript: nil,
103 Sequence: 4294967295,
105 TxOut: []*wire.TxOut{{
111 pkScript := mustParseShortForm("NOP NOP NOP NOP NOP NOP NOP NOP NOP" +
114 vm, err := NewEngine(pkScript, tx, 0, 0, nil, nil, 0)
116 t.Errorf("failed to create script: %v", err)
119 for i := 0; i < len(pkScript)-1; i++ {
120 done, err := vm.Step()
122 t.Fatalf("failed to step %dth time: %v", i, err)
125 t.Fatalf("finshed early on %dth time", i)
128 err = vm.CheckErrorCondition(false)
129 if !IsErrorCode(err, ErrScriptUnfinished) {
130 t.Fatalf("got unexepected error %v on %dth iteration",
134 done, err := vm.Step()
136 t.Fatalf("final step failed %v", err)
139 t.Fatalf("final step isn't done!")
142 err = vm.CheckErrorCondition(false)
144 t.Errorf("unexpected error %v on final check", err)
148 // TestInvalidFlagCombinations ensures the script engine returns the expected
149 // error when disallowed flag combinations are specified.
150 func TestInvalidFlagCombinations(t *testing.T) {
153 tests := []ScriptFlags{
154 ScriptVerifyCleanStack,
157 // tx with almost empty scripts.
162 PreviousOutPoint: wire.OutPoint{
163 Hash: chainhash.Hash([32]byte{
164 0xc9, 0x97, 0xa5, 0xe5,
165 0x6e, 0x10, 0x41, 0x02,
166 0xfa, 0x20, 0x9c, 0x6a,
167 0x85, 0x2d, 0xd9, 0x06,
168 0x60, 0xa2, 0x0b, 0x2d,
169 0x9c, 0x35, 0x24, 0x23,
170 0xed, 0xce, 0x25, 0x85,
171 0x7f, 0xcd, 0x37, 0x04,
175 SignatureScript: []uint8{OP_NOP},
176 Sequence: 4294967295,
179 TxOut: []*wire.TxOut{
187 pkScript := []byte{OP_NOP}
189 for i, test := range tests {
190 _, err := NewEngine(pkScript, tx, 0, test, nil, nil, -1)
191 if !IsErrorCode(err, ErrInvalidFlags) {
192 t.Fatalf("TestInvalidFlagCombinations #%d unexpected "+
198 // TestCheckPubKeyEncoding ensures the internal checkPubKeyEncoding function
199 // works as expected.
200 func TestCheckPubKeyEncoding(t *testing.T) {
209 name: "uncompressed ok",
210 key: hexToBytes("0411db93e1dcdb8a016b49840f8c53bc1eb68" +
211 "a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf" +
212 "9744464f82e160bfa9b8b64f9d4c03f999b8643f656b" +
217 name: "compressed ok",
218 key: hexToBytes("02ce0b14fb842b1ba549fdd675c98075f12e9" +
219 "c510f8ef52bd021a9a1f4809d3b4d"),
223 name: "compressed ok",
224 key: hexToBytes("032689c7c2dab13309fb143e0e8fe39634252" +
225 "1887e976690b6b47f5b2a4b7d448e"),
230 key: hexToBytes("0679be667ef9dcbbac55a06295ce870b07029" +
231 "bfcdb2dce28d959f2815b16f81798483ada7726a3c46" +
232 "55da4fbfc0e1108a8fd17b448a68554199c47d08ffb1" +
243 vm := Engine{flags: ScriptVerifyStrictEncoding}
244 for _, test := range tests {
245 err := vm.checkPubKeyEncoding(test.key)
246 if err != nil && test.isValid {
247 t.Errorf("checkSignatureEncoding test '%s' failed "+
248 "when it should have succeeded: %v", test.name,
250 } else if err == nil && !test.isValid {
251 t.Errorf("checkSignatureEncooding test '%s' succeeded "+
252 "when it should have failed", test.name)
258 // TestCheckSignatureEncoding ensures the internal checkSignatureEncoding
259 // function works as expected.
260 func TestCheckSignatureEncoding(t *testing.T) {
269 name: "valid signature",
270 sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
271 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
272 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
283 sig: hexToBytes("314402204e45e16932b8af514961a1d3a1a25" +
284 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
285 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
290 name: "bad 1st int marker magic",
291 sig: hexToBytes("304403204e45e16932b8af514961a1d3a1a25" +
292 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
293 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
298 name: "bad 2nd int marker",
299 sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
300 "fdf3f4f7732e9d624c6c61548ab5fb8cd41032018152" +
301 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
307 sig: hexToBytes("304302204e45e16932b8af514961a1d3a1a25" +
308 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
309 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
315 sig: hexToBytes("304502204e45e16932b8af514961a1d3a1a25" +
316 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
317 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
323 sig: hexToBytes("304402424e45e16932b8af514961a1d3a1a25" +
324 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
325 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
331 sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
332 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022118152" +
333 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
339 sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
340 "fdf3f4f7732e9d624c6c61548ab5fb8cd41021918152" +
341 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
346 name: "trailing crap",
347 sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
348 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
349 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
350 "82221a8768d1d0901"),
355 sig: hexToBytes("30440220fffffffffffffffffffffffffffff" +
356 "ffebaaedce6af48a03bbfd25e8cd0364141022018152" +
357 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
363 sig: hexToBytes("30440220fffffffffffffffffffffffffffff" +
364 "ffebaaedce6af48a03bbfd25e8cd0364142022018152" +
365 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
371 sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
372 "fdf3f4f7732e9d624c6c61548ab5fb8cd410220fffff" +
373 "ffffffffffffffffffffffffffebaaedce6af48a03bb" +
379 sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
380 "fdf3f4f7732e9d624c6c61548ab5fb8cd410220fffff" +
381 "ffffffffffffffffffffffffffebaaedce6af48a03bb" +
387 sig: hexToBytes("302402000220181522ec8eca07de4860a4acd" +
388 "d12909d831cc56cbbac4622082221a8768d1d09"),
393 sig: hexToBytes("302402204e45e16932b8af514961a1d3a1a25" +
394 "fdf3f4f7732e9d624c6c61548ab5fb8cd410200"),
398 name: "extra R padding",
399 sig: hexToBytes("30450221004e45e16932b8af514961a1d3a1a" +
400 "25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181" +
401 "522ec8eca07de4860a4acdd12909d831cc56cbbac462" +
402 "2082221a8768d1d09"),
406 name: "extra S padding",
407 sig: hexToBytes("304502204e45e16932b8af514961a1d3a1a25" +
408 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022100181" +
409 "522ec8eca07de4860a4acdd12909d831cc56cbbac462" +
410 "2082221a8768d1d09"),
415 vm := Engine{flags: ScriptVerifyStrictEncoding}
416 for _, test := range tests {
417 err := vm.checkSignatureEncoding(test.sig)
418 if err != nil && test.isValid {
419 t.Errorf("checkSignatureEncoding test '%s' failed "+
420 "when it should have succeeded: %v", test.name,
422 } else if err == nil && !test.isValid {
423 t.Errorf("checkSignatureEncooding test '%s' succeeded "+
424 "when it should have failed", test.name)