Skip to content

Commit

Permalink
Support multiple nonces and messages for adaptor signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
Tibo-lg committed Feb 4, 2021
1 parent 78c5a6c commit 649af4e
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 75 deletions.
56 changes: 38 additions & 18 deletions include/cfddlc/cfddlc_transactions.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,26 +261,27 @@ class CFD_DLC_EXPORT DlcManager {
*
* @param cet the CET to generate the signature for.
* @param oracle_pubkey the pubkey of the oracle for the associated event.
* @param oracle_r_value the r value that the oracle will use for the
* @param oracle_r_values the set of r values that the oracle will use for the
* associated event.
* @param funding_sk the private key to generate the signature with.
* @param funding_script_pubkey the script pubkey of the fund output.
* @param fund_output_amount the value of the fund output.
* @param msg the message for the outcome corresponding to the given CET.
* @param msgs the set of messages for the outcome corresponding to the given
* CET.
* @return AdaptorPair an adaptor signature and its dleq proof.
*/
static AdaptorPair CreateCetAdaptorSignature(
const TransactionController& cet, const SchnorrPubkey& oracle_pubkey,
const SchnorrPubkey& oracle_r_value, const Privkey& funding_sk,
const Script& funding_script_pubkey, const Amount& fund_output_amount,
const ByteData256& msg);
const std::vector<SchnorrPubkey>& oracle_r_values,
const Privkey& funding_sk, const Script& funding_script_pubkey,
const Amount& fund_output_amount, const std::vector<ByteData256>& msgs);

/**
* @brief Create a Cet Adaptor Signatures object
*
* @param cets the cets to generate adaptor signatures for.
* @param oracle_pubkey the pubkey of the oracle for the associated event.
* @param oracle_r_value the r value that the oracle will use for the
* @param oracle_r_values the set of r value that the oracle will use for the
* associated event.
* @param funding_sk the private key to generate the signature with.
* @param funding_script_pubkey the script pubkey of the fund output.
Expand All @@ -291,9 +292,11 @@ class CFD_DLC_EXPORT DlcManager {
*/
static std::vector<AdaptorPair> CreateCetAdaptorSignatures(
const std::vector<TransactionController>& cets,
const SchnorrPubkey& oracle_pubkey, const SchnorrPubkey& oracle_r_value,
const SchnorrPubkey& oracle_pubkey,
const std::vector<SchnorrPubkey>& oracle_r_values,
const Privkey& funding_sk, const Script& funding_script_pubkey,
const Amount& fund_output_amount, const std::vector<ByteData256>& msgs);
const Amount& fund_output_amount,
const std::vector<std::vector<ByteData256>>& msgs);

/**
* @brief Verify that a signature for a fund transaction is valid.
Expand Down Expand Up @@ -321,19 +324,21 @@ class CFD_DLC_EXPORT DlcManager {
* @param pubkey the public key to verify the signature against.
* @param oracle_pubkey the public key of the oracle used for the associated
* event.
* @param oracle_r_value the r_value that the oracle will used to create a
* signature over the outcome of the associated event.
* @param oracle_r_values the r_values that the oracle will used to create
* signatures over the outcome of the associated event.
* @param funding_script_pubkey the script pubkey of the fund output.
* @param fund_output_amount the value of the fund output.
* @param msg the hash of the event outcome for the given CET.
* @param msgs the hashes of the value representing the event outcome for the
* given CET.
* @return true
* @return false
*/
static bool VerifyCetAdaptorSignature(
const AdaptorPair& adaptor_pair, const TransactionController& cet,
const Pubkey& pubkey, const SchnorrPubkey& oracle_pubkey,
const SchnorrPubkey& oracle_r_value, const Script& funding_script_pubkey,
const Amount& fund_output_amount, const ByteData256& msg);
const std::vector<SchnorrPubkey>& oracle_r_values,
const Script& funding_script_pubkey, const Amount& fund_output_amount,
const std::vector<ByteData256>& msgs);

/**
* @brief Sign a CET transaction using a counter party adaptor signature that
Expand All @@ -342,8 +347,8 @@ class CFD_DLC_EXPORT DlcManager {
*
* @param cet the CET to which the signatures will be added.
* @param adaptor_sig the adaptor signature of the counterparty.
* @param oracle_signature the signature of the oracle over the corresponding
* event outcome.
* @param oracle_signatures the set of signatures from the oracle over the
* corresponding event outcome.
* @param funding_sk the private key to generate own signature with.
* @param funding_script_pubkey the script pubkey of the fund output.
* @param fund_tx_id the transaction id of the fund transactions.
Expand All @@ -352,7 +357,7 @@ class CFD_DLC_EXPORT DlcManager {
*/
static void SignCet(TransactionController* cet,
const AdaptorSignature& adaptor_sig,
const SchnorrSignature& oracle_signature,
const std::vector<SchnorrSignature>& oracle_signatures,
const Privkey funding_sk,
const Script& funding_script_pubkey,
const Txid& fund_tx_id, uint32_t fund_vout,
Expand All @@ -378,8 +383,9 @@ class CFD_DLC_EXPORT DlcManager {
static bool VerifyCetAdaptorSignatures(
const std::vector<TransactionController>& cets,
const std::vector<AdaptorPair>& signature_and_proofs,
const std::vector<ByteData256>& msgs, const Pubkey& pubkey,
const SchnorrPubkey& oracle_pubkey, const SchnorrPubkey& oracle_r_value,
const std::vector<std::vector<ByteData256>>& msgs, const Pubkey& pubkey,
const SchnorrPubkey& oracle_pubkey,
const std::vector<SchnorrPubkey>& oracle_r_value,
const Script& funding_script_pubkey, const Amount& fund_output_amount);

/**
Expand Down Expand Up @@ -633,6 +639,20 @@ class CFD_DLC_EXPORT DlcManager {
const PartyParams& params, uint64_t fee_rate,
Amount option_premium = Amount::CreateBySatoshiAmount(0),
Address premium_dest = Address());

/**
* @brief Computes an adaptor point from a set of messages, r_values and a
* public key.
*
* @param msgs the messages to use to compute the signature points.
* @param r_values the r_values to use to compute the signature points.
* @param pubkey the public key to use to compute the signature points.
* @return Pubkey the adaptor point corresponding to the sum of the computed
* signature points.
*/
static Pubkey ComputeAdaptorPoint(const std::vector<ByteData256>& msgs,
const std::vector<SchnorrPubkey>& r_values,
const SchnorrPubkey& pubkey);
};

} // namespace dlc
Expand Down
67 changes: 50 additions & 17 deletions src/cfddlc_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,12 @@ bool DlcManager::VerifyFundTxSignature(const TransactionController& fund_tx,

AdaptorPair DlcManager::CreateCetAdaptorSignature(
const TransactionController& cet, const SchnorrPubkey& oracle_pubkey,
const SchnorrPubkey& oracle_r_value, const Privkey& funding_sk,
const Script& funding_script_pubkey, const Amount& total_collateral,
const ByteData256& msg) {
const std::vector<SchnorrPubkey>& oracle_r_values,
const Privkey& funding_sk, const Script& funding_script_pubkey,
const Amount& total_collateral, const std::vector<ByteData256>& msgs) {
auto adaptor_point =
SchnorrUtil::ComputeSigPoint(msg, oracle_r_value, oracle_pubkey);
ComputeAdaptorPoint(msgs, oracle_r_values, oracle_pubkey);

auto sig_hash = cet.GetTransaction().GetSignatureHash(
0, funding_script_pubkey.GetData(), SigHashType(), total_collateral,
WitnessVersion::kVersion0);
Expand All @@ -204,9 +205,10 @@ AdaptorPair DlcManager::CreateCetAdaptorSignature(

std::vector<AdaptorPair> DlcManager::CreateCetAdaptorSignatures(
const std::vector<TransactionController>& cets,
const SchnorrPubkey& oracle_pubkey, const SchnorrPubkey& oracle_r_value,
const Privkey& funding_sk, const Script& funding_script_pubkey,
const Amount& total_collateral, const std::vector<ByteData256>& msgs) {
const SchnorrPubkey& oracle_pubkey,
const std::vector<SchnorrPubkey>& oracle_r_value, const Privkey& funding_sk,
const Script& funding_script_pubkey, const Amount& total_collateral,
const std::vector<std::vector<ByteData256>>& msgs) {
size_t nb = cets.size();
if (nb != msgs.size()) {
throw CfdException(CfdError::kCfdIllegalArgumentError,
Expand All @@ -226,10 +228,11 @@ std::vector<AdaptorPair> DlcManager::CreateCetAdaptorSignatures(
bool DlcManager::VerifyCetAdaptorSignature(
const AdaptorPair& adaptor_pair, const TransactionController& cet,
const Pubkey& pubkey, const SchnorrPubkey& oracle_pubkey,
const SchnorrPubkey& oracle_r_value, const Script& funding_script_pubkey,
const Amount& total_collateral, const ByteData256& msg) {
const std::vector<SchnorrPubkey>& oracle_r_values,
const Script& funding_script_pubkey, const Amount& total_collateral,
const std::vector<ByteData256>& msgs) {
auto adaptor_point =
SchnorrUtil::ComputeSigPoint(msg, oracle_r_value, oracle_pubkey);
ComputeAdaptorPoint(msgs, oracle_r_values, oracle_pubkey);
auto sig_hash = cet.GetTransaction().GetSignatureHash(
0, funding_script_pubkey.GetData(), SigHashType(), total_collateral,
WitnessVersion::kVersion0);
Expand All @@ -240,8 +243,9 @@ bool DlcManager::VerifyCetAdaptorSignature(
bool DlcManager::VerifyCetAdaptorSignatures(
const std::vector<TransactionController>& cets,
const std::vector<AdaptorPair>& signature_and_proofs,
const std::vector<ByteData256>& msgs, const Pubkey& pubkey,
const SchnorrPubkey& oracle_pubkey, const SchnorrPubkey& oracle_r_value,
const std::vector<std::vector<ByteData256>>& msgs, const Pubkey& pubkey,
const SchnorrPubkey& oracle_pubkey,
const std::vector<SchnorrPubkey>& oracle_r_values,
const Script& funding_script_pubkey, const Amount& total_collateral) {
auto nb = cets.size();
if (nb != signature_and_proofs.size() || nb != msgs.size()) {
Expand All @@ -254,21 +258,32 @@ bool DlcManager::VerifyCetAdaptorSignatures(

for (size_t i = 0; i < nb && all_valid; i++) {
all_valid &= VerifyCetAdaptorSignature(
signature_and_proofs[i], cets[i], pubkey, oracle_pubkey, oracle_r_value,
funding_script_pubkey, total_collateral, msgs[i]);
signature_and_proofs[i], cets[i], pubkey, oracle_pubkey,
oracle_r_values, funding_script_pubkey, total_collateral, msgs[i]);
}

return all_valid;
}

void DlcManager::SignCet(TransactionController* cet,
const AdaptorSignature& adaptor_sig,
const SchnorrSignature& oracle_signature,
const std::vector<SchnorrSignature>& oracle_signatures,
const Privkey funding_sk,
const Script& funding_script_pubkey,
const Txid& fund_tx_id, uint32_t fund_vout,
const Amount& fund_amount) {
auto adaptor_secret = oracle_signature.GetPrivkey();
if (oracle_signatures.size() < 1) {
throw CfdException(CfdError::kCfdIllegalArgumentError,
"No oracle signature provided.");
}

auto adaptor_secret = oracle_signatures[0].GetPrivkey();

for (size_t i = 1; i < oracle_signatures.size(); i++) {
adaptor_secret = adaptor_secret.CreateTweakAdd(
ByteData256(oracle_signatures[i].GetPrivkey().GetData()));
}

auto adapted_sig = AdaptorUtil::Adapt(adaptor_sig, adaptor_secret);
auto sig_hash = cet->GetTransaction().GetSignatureHash(
0, funding_script_pubkey.GetData(), SigHashType(), fund_amount,
Expand All @@ -289,7 +304,7 @@ void DlcManager::SignCet(TransactionController* cet,
throw new CfdException(CfdError::kCfdIllegalArgumentError,
"Public key not part of the multi sig script.");
}
}
} // namespace dlc

ByteData DlcManager::GetRawFundingTransactionInputSignature(
const TransactionController& funding_transaction, const Privkey& privkey,
Expand Down Expand Up @@ -519,5 +534,23 @@ std::tuple<TxOut, uint64_t, uint64_t> DlcManager::GetChangeOutputAndFees(

return std::make_tuple(change_output, fund_fee, cet_fee);
}

Pubkey DlcManager::ComputeAdaptorPoint(
const std::vector<ByteData256>& msgs,
const std::vector<SchnorrPubkey>& r_values, const SchnorrPubkey& pubkey) {
if (r_values.size() != msgs.size()) {
throw CfdException(CfdError::kCfdIllegalArgumentError,
"Number of r values and messages must match.");
}

std::vector<Pubkey> sigpoints;

for (size_t i = 0; i < r_values.size(); i++) {
sigpoints.push_back(
SchnorrUtil::ComputeSigPoint(msgs[i], r_values[i], pubkey));
}

return sigpoints.size() > 1 ? Pubkey::CombinePubkey(sigpoints) : sigpoints[0];
}
} // namespace dlc
} // namespace cfd
Loading

0 comments on commit 649af4e

Please sign in to comment.