verifyWitnessProgram validates the stored witness program using the passed witness as input.
(witness wire.TxWitness)
| 567 | // verifyWitnessProgram validates the stored witness program using the passed |
| 568 | // witness as input. |
| 569 | func (vm *Engine) verifyWitnessProgram(witness wire.TxWitness) error { |
| 570 | switch { |
| 571 | |
| 572 | // We're attempting to verify a base (witness version 0) segwit output, |
| 573 | // so we'll be looking for either a p2wsh or a p2wkh spend. |
| 574 | case vm.isWitnessVersionActive(BaseSegwitWitnessVersion): |
| 575 | switch len(vm.witnessProgram) { |
| 576 | case payToWitnessPubKeyHashDataSize: // P2WKH |
| 577 | // The witness stack should consist of exactly two |
| 578 | // items: the signature, and the pubkey. |
| 579 | if len(witness) != 2 { |
| 580 | err := fmt.Sprintf("should have exactly two "+ |
| 581 | "items in witness, instead have %v", len(witness)) |
| 582 | return scriptError(ErrWitnessProgramMismatch, err) |
| 583 | } |
| 584 | |
| 585 | // Now we'll resume execution as if it were a regular |
| 586 | // p2pkh transaction. |
| 587 | pkScript, err := payToPubKeyHashScript(vm.witnessProgram) |
| 588 | if err != nil { |
| 589 | return err |
| 590 | } |
| 591 | |
| 592 | const scriptVersion = 0 |
| 593 | err = checkScriptParses(vm.version, pkScript) |
| 594 | if err != nil { |
| 595 | return err |
| 596 | } |
| 597 | |
| 598 | // Set the stack to the provided witness stack, then |
| 599 | // append the pkScript generated above as the next |
| 600 | // script to execute. |
| 601 | vm.scripts = append(vm.scripts, pkScript) |
| 602 | vm.SetStack(witness) |
| 603 | |
| 604 | case payToWitnessScriptHashDataSize: // P2WSH |
| 605 | // Additionally, The witness stack MUST NOT be empty at |
| 606 | // this point. |
| 607 | if len(witness) == 0 { |
| 608 | return scriptError(ErrWitnessProgramEmpty, "witness "+ |
| 609 | "program empty passed empty witness") |
| 610 | } |
| 611 | |
| 612 | // Obtain the witness script which should be the last |
| 613 | // element in the passed stack. The size of the script |
| 614 | // MUST NOT exceed the max script size. |
| 615 | witnessScript := witness[len(witness)-1] |
| 616 | if len(witnessScript) > MaxScriptSize { |
| 617 | str := fmt.Sprintf("witnessScript size %d "+ |
| 618 | "is larger than max allowed size %d", |
| 619 | len(witnessScript), MaxScriptSize) |
| 620 | return scriptError(ErrScriptTooBig, str) |
| 621 | } |
| 622 | |
| 623 | // Ensure that the serialized pkScript at the end of |
| 624 | // the witness stack matches the witness program. |
| 625 | witnessHash := sha256.Sum256(witnessScript) |
| 626 | if !bytes.Equal(witnessHash[:], vm.witnessProgram) { |
no test coverage detected