From b1064b0faabc1b1c09fdbb78cd8d96fc55293463 Mon Sep 17 00:00:00 2001 From: Matthew Black Date: Tue, 16 Feb 2021 03:11:35 -0500 Subject: [PATCH] Enable fewer messages than rvalues Add ability to pass in less messages than r values for a particular CET Add OutOfRange guard to ensure r values length greater or equal to messages length Add CfdException to CreateCetAdaptorSignatures and VerifyCetAdaptorSignatures if r values length is less than messages length Add tests for AdaptorSigMultipleNoncesWithFewerMessagesThanNonces and AdaptorSigMultipleNoncesWithMoreMessagesThanNoncesFails --- src/cfddlc_transactions.cpp | 24 +++++++++++-- test/test_cfddlc_transactions.cpp | 60 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/cfddlc_transactions.cpp b/src/cfddlc_transactions.cpp index 531a052..5f83fca 100644 --- a/src/cfddlc_transactions.cpp +++ b/src/cfddlc_transactions.cpp @@ -206,7 +206,7 @@ AdaptorPair DlcManager::CreateCetAdaptorSignature( std::vector DlcManager::CreateCetAdaptorSignatures( const std::vector& cets, const SchnorrPubkey& oracle_pubkey, - const std::vector& oracle_r_value, const Privkey& funding_sk, + const std::vector& oracle_r_values, const Privkey& funding_sk, const Script& funding_script_pubkey, const Amount& total_collateral, const std::vector>& msgs) { size_t nb = cets.size(); @@ -217,8 +217,17 @@ std::vector DlcManager::CreateCetAdaptorSignatures( std::vector sigs; for (size_t i = 0; i < nb; i++) { + if (oracle_r_values.size() < msgs[i].size()) { + throw CfdException( + CfdError::kCfdIllegalArgumentError, + "Number of r values must be greater or equal to number of messages."); + } + std::vector r_values; + for (size_t j = 0; j < msgs[i].size(); j++) { + r_values.push_back(oracle_r_values[j]); + } sigs.push_back(CreateCetAdaptorSignature( - cets[i], oracle_pubkey, oracle_r_value, funding_sk, + cets[i], oracle_pubkey, r_values, funding_sk, funding_script_pubkey, total_collateral, msgs[i])); } @@ -257,9 +266,18 @@ bool DlcManager::VerifyCetAdaptorSignatures( bool all_valid = true; for (size_t i = 0; i < nb && all_valid; i++) { + if (oracle_r_values.size() < msgs[i].size()) { + throw CfdException( + CfdError::kCfdIllegalArgumentError, + "Number of r values must be greater or equal to number of messages."); + } + std::vector r_values; + for (size_t j = 0; j < msgs[i].size(); j++) { + r_values.push_back(oracle_r_values[j]); + } all_valid &= VerifyCetAdaptorSignature( signature_and_proofs[i], cets[i], pubkey, oracle_pubkey, - oracle_r_values, funding_script_pubkey, total_collateral, msgs[i]); + r_values, funding_script_pubkey, total_collateral, msgs[i]); } return all_valid; diff --git a/test/test_cfddlc_transactions.cpp b/test/test_cfddlc_transactions.cpp index 2d94e14..9d7684b 100644 --- a/test/test_cfddlc_transactions.cpp +++ b/test/test_cfddlc_transactions.cpp @@ -43,6 +43,10 @@ const std::vector WIN_MESSAGES_HASH = { HashUtil::Sha256(WIN_MESSAGES[0]), HashUtil::Sha256(WIN_MESSAGES[1])}; const std::vector LOSE_MESSAGES_HASH = { HashUtil::Sha256(LOSE_MESSAGES[0]), HashUtil::Sha256(LOSE_MESSAGES[1])}; +const std::vector WIN_MESSAGES_HASH_FEWER_MESSAGES = { + HashUtil::Sha256(WIN_MESSAGES[0])}; +const std::vector LOSE_MESSAGES_HASH_FEWER_MESSAGES = { + HashUtil::Sha256(LOSE_MESSAGES[0])}; const std::vector> MESSAGES_HASH = { WIN_MESSAGES_HASH, LOSE_MESSAGES_HASH}; const Privkey ORACLE_PRIVKEY( @@ -568,3 +572,59 @@ TEST(DlcManager, AdaptorSigMultipleNonces) { fund_amount, WitnessVersion::kVersion0); EXPECT_TRUE(is_valid); } + +TEST(DlcManager, AdaptorSigMultipleNoncesWithFewerMessagesThanNonces) { + std::vector outcomes = {{WIN_AMOUNT, LOSE_AMOUNT}, + {LOSE_AMOUNT, WIN_AMOUNT}}; + auto dlc_transactions = DlcManager::CreateDlcTransactions( + outcomes, LOCAL_PARAMS, REMOTE_PARAMS, REFUND_LOCKTIME, 1, PREMIUM_DEST, + OPTION_PREMIUM); + auto fund_transaction = dlc_transactions.fund_transaction; + auto cets = dlc_transactions.cets; + auto cet0 = cets[0]; + auto lock_script = DlcManager::CreateFundTxLockingScript(LOCAL_FUND_PUBKEY, + REMOTE_FUND_PUBKEY); + + auto fund_amount = fund_transaction.GetTransaction().GetTxOut(0).GetValue(); + auto fund_txid = fund_transaction.GetTransaction().GetTxid(); + + auto adaptor_pairs = DlcManager::CreateCetAdaptorSignatures( + cets, ORACLE_PUBKEY, ORACLE_R_POINTS, LOCAL_FUND_PRIVKEY, lock_script, + fund_amount, {WIN_MESSAGES_HASH_FEWER_MESSAGES, LOSE_MESSAGES_HASH_FEWER_MESSAGES}); + + EXPECT_TRUE(DlcManager::VerifyCetAdaptorSignature( + adaptor_pairs[1], cets[1], LOCAL_FUND_PUBKEY, ORACLE_PUBKEY, + {ORACLE_R_POINTS[0]}, lock_script, fund_amount, LOSE_MESSAGES_HASH_FEWER_MESSAGES)); + + auto adaptor_secret = ORACLE_SIGNATURES[0].GetPrivkey(); + auto adapted_sig = + AdaptorUtil::Adapt(adaptor_pairs[0].signature, adaptor_secret); + + auto is_valid = cet0.VerifyInputSignature( + adapted_sig, LOCAL_FUND_PUBKEY, fund_txid, 0, lock_script, SigHashType(), + fund_amount, WitnessVersion::kVersion0); + EXPECT_TRUE(is_valid); +} + +TEST(DlcManager, AdaptorSigMultipleNoncesWithMoreMessagesThanNoncesFails) { + std::vector outcomes = {{WIN_AMOUNT, LOSE_AMOUNT}, + {LOSE_AMOUNT, WIN_AMOUNT}}; + auto dlc_transactions = DlcManager::CreateDlcTransactions( + outcomes, LOCAL_PARAMS, REMOTE_PARAMS, REFUND_LOCKTIME, 1, PREMIUM_DEST, + OPTION_PREMIUM); + auto fund_transaction = dlc_transactions.fund_transaction; + auto cets = dlc_transactions.cets; + auto cet0 = cets[0]; + auto lock_script = DlcManager::CreateFundTxLockingScript(LOCAL_FUND_PUBKEY, + REMOTE_FUND_PUBKEY); + + auto fund_amount = fund_transaction.GetTransaction().GetTxOut(0).GetValue(); + auto fund_txid = fund_transaction.GetTransaction().GetTxid(); + + // Act/Assert + EXPECT_THROW(DlcManager::CreateCetAdaptorSignatures( + cets, ORACLE_PUBKEY, ORACLE_R_POINTS, LOCAL_FUND_PRIVKEY, lock_script, + fund_amount, {WIN_MESSAGES_HASH, LOSE_MESSAGES_HASH, + WIN_MESSAGES_HASH_FEWER_MESSAGES, LOSE_MESSAGES_HASH_FEWER_MESSAGES}), + CfdException); +}