| 556 | } |
| 557 | |
| 558 | static bool SignTaproot(const SigningProvider& provider, const BaseSignatureCreator& creator, const WitnessV1Taproot& output, SignatureData& sigdata, std::vector<valtype>& result) |
| 559 | { |
| 560 | TaprootSpendData spenddata; |
| 561 | TaprootBuilder builder; |
| 562 | |
| 563 | // Gather information about this output. |
| 564 | if (provider.GetTaprootSpendData(output, spenddata)) { |
| 565 | sigdata.tr_spenddata.Merge(spenddata); |
| 566 | } |
| 567 | if (provider.GetTaprootBuilder(output, builder)) { |
| 568 | sigdata.tr_builder = builder; |
| 569 | } |
| 570 | if (auto agg_keys = provider.GetAllMuSig2ParticipantPubkeys(); !agg_keys.empty()) { |
| 571 | sigdata.musig2_pubkeys.insert(agg_keys.begin(), agg_keys.end()); |
| 572 | } |
| 573 | |
| 574 | |
| 575 | // Try key path spending. |
| 576 | { |
| 577 | KeyOriginInfo internal_key_info; |
| 578 | if (provider.GetKeyOriginByXOnly(sigdata.tr_spenddata.internal_key, internal_key_info)) { |
| 579 | auto it = sigdata.taproot_misc_pubkeys.find(sigdata.tr_spenddata.internal_key); |
| 580 | if (it == sigdata.taproot_misc_pubkeys.end()) { |
| 581 | sigdata.taproot_misc_pubkeys.emplace(sigdata.tr_spenddata.internal_key, std::make_pair(std::set<uint256>(), internal_key_info)); |
| 582 | } |
| 583 | } |
| 584 | |
| 585 | KeyOriginInfo output_key_info; |
| 586 | if (provider.GetKeyOriginByXOnly(output, output_key_info)) { |
| 587 | auto it = sigdata.taproot_misc_pubkeys.find(output); |
| 588 | if (it == sigdata.taproot_misc_pubkeys.end()) { |
| 589 | sigdata.taproot_misc_pubkeys.emplace(output, std::make_pair(std::set<uint256>(), output_key_info)); |
| 590 | } |
| 591 | } |
| 592 | |
| 593 | auto make_keypath_sig = [&](const XOnlyPubKey& pk, const uint256* merkle_root) { |
| 594 | std::vector<unsigned char> sig; |
| 595 | if (creator.CreateSchnorrSig(provider, sig, pk, nullptr, merkle_root, SigVersion::TAPROOT)) { |
| 596 | sigdata.taproot_key_path_sig = sig; |
| 597 | } else { |
| 598 | SignMuSig2(creator, sigdata, provider, sig, pk, merkle_root, /*leaf_hash=*/nullptr, SigVersion::TAPROOT); |
| 599 | } |
| 600 | }; |
| 601 | |
| 602 | // First try signing with internal key |
| 603 | if (sigdata.taproot_key_path_sig.size() == 0) { |
| 604 | make_keypath_sig(sigdata.tr_spenddata.internal_key, &sigdata.tr_spenddata.merkle_root); |
| 605 | } |
| 606 | // Try signing with output key if still no signature |
| 607 | if (sigdata.taproot_key_path_sig.size() == 0) { |
| 608 | make_keypath_sig(output, nullptr); |
| 609 | } |
| 610 | if (sigdata.taproot_key_path_sig.size()) { |
| 611 | result = Vector(sigdata.taproot_key_path_sig); |
| 612 | return true; |
| 613 | } |
| 614 | } |
| 615 |
no test coverage detected