| 143 | } |
| 144 | |
| 145 | bool MutableTransactionSignatureCreator::CreateMuSig2PartialSig(const SigningProvider& provider, uint256& partial_sig, const CPubKey& aggregate_pubkey, const CPubKey& script_pubkey, const CPubKey& part_pubkey, const uint256* leaf_hash, const std::vector<std::pair<uint256, bool>>& tweaks, SigVersion sigversion, const SignatureData& sigdata) const |
| 146 | { |
| 147 | assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT); |
| 148 | |
| 149 | // Retrieve private key |
| 150 | CKey key; |
| 151 | if (!provider.GetKey(part_pubkey.GetID(), key)) return false; |
| 152 | |
| 153 | // Retrieve participant pubkeys |
| 154 | auto it = sigdata.musig2_pubkeys.find(aggregate_pubkey); |
| 155 | if (it == sigdata.musig2_pubkeys.end()) return false; |
| 156 | const std::vector<CPubKey>& pubkeys = it->second; |
| 157 | if (std::find(pubkeys.begin(), pubkeys.end(), part_pubkey) == pubkeys.end()) return {}; |
| 158 | |
| 159 | // Retrieve pubnonces |
| 160 | auto this_leaf_aggkey = std::make_pair(script_pubkey, leaf_hash ? *leaf_hash : uint256()); |
| 161 | auto pubnonce_it = sigdata.musig2_pubnonces.find(this_leaf_aggkey); |
| 162 | if (pubnonce_it == sigdata.musig2_pubnonces.end()) return false; |
| 163 | const std::map<CPubKey, std::vector<uint8_t>>& pubnonces = pubnonce_it->second; |
| 164 | |
| 165 | // Check if enough pubnonces |
| 166 | if (pubnonces.size() != pubkeys.size()) return false; |
| 167 | |
| 168 | // Compute sighash |
| 169 | std::optional<uint256> sighash = ComputeSchnorrSignatureHash(leaf_hash, sigversion); |
| 170 | if (!sighash.has_value()) return false; |
| 171 | |
| 172 | // Retrieve the secnonce |
| 173 | auto part_pubnonce_it = pubnonces.find(part_pubkey); |
| 174 | if (part_pubnonce_it == pubnonces.end()) return false; |
| 175 | uint256 session_id = MuSig2SessionID(script_pubkey, part_pubkey, *sighash, part_pubnonce_it->second); |
| 176 | std::optional<std::reference_wrapper<MuSig2SecNonce>> secnonce = provider.GetMuSig2SecNonce(session_id); |
| 177 | if (!secnonce || !secnonce->get().IsValid()) return false; |
| 178 | |
| 179 | // Compute the sig |
| 180 | std::optional<uint256> sig = ::CreateMuSig2PartialSig(*sighash, key, aggregate_pubkey, pubkeys, pubnonces, *secnonce, tweaks); |
| 181 | if (!sig) return false; |
| 182 | partial_sig = std::move(*sig); |
| 183 | |
| 184 | // Delete the secnonce now that we're done with it |
| 185 | assert(!secnonce->get().IsValid()); |
| 186 | provider.DeleteMuSig2Session(session_id); |
| 187 | |
| 188 | return true; |
| 189 | } |
| 190 | |
| 191 | bool MutableTransactionSignatureCreator::CreateMuSig2AggregateSig(const std::vector<CPubKey>& participants, std::vector<uint8_t>& sig, const CPubKey& aggregate_pubkey, const CPubKey& script_pubkey, const uint256* leaf_hash, const std::vector<std::pair<uint256, bool>>& tweaks, SigVersion sigversion, const SignatureData& sigdata) const |
| 192 | { |
no test coverage detected