From 420de43c1ce3d897517249958dab0d11c320cd37 Mon Sep 17 00:00:00 2001 From: Allen Piscitello Date: Wed, 24 Aug 2022 09:42:29 -0500 Subject: [PATCH 1/3] removing code to blind issuances. PSET should be modified to include an option to blind or unblind issuances, defaulting to unblind. --- src/blindpsbt.cpp | 91 ++++++++++++------------------------------- src/psbt.cpp | 2 +- src/wallet/wallet.cpp | 4 +- 3 files changed, 27 insertions(+), 70 deletions(-) diff --git a/src/blindpsbt.cpp b/src/blindpsbt.cpp index a1b21e5dd0..f4547041dc 100644 --- a/src/blindpsbt.cpp +++ b/src/blindpsbt.cpp @@ -386,7 +386,7 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map 0; + bool blind_issuance = input.m_issuance_inflation_keys_commitment.IsCommitment() || input.m_issuance_value_commitment.IsCommitment(); - if (input.m_issuance_blinding_nonce.IsNull() && input.m_issuance_inflation_keys_amount) { + if (input.m_issuance_blinding_nonce.IsNull() && (input.m_issuance_inflation_keys_amount != std::nullopt || input.m_issuance_inflation_keys_commitment.IsCommitment())) { // New issuance, do reissuance token things CalculateReissuanceToken(reissuance_asset, entropy, blind_issuance); // Add the reissuance_asset to the list of input assets fixed_input_tags.emplace_back(); memcpy(fixed_input_tags.back().data, reissuance_asset.begin(), 32); ephemeral_input_tags.emplace_back(); - if (secp256k1_generator_generate(secp256k1_blind_context, &ephemeral_input_tags.back(), reissuance_asset.begin()) != 1) { - return BlindingStatus::INVALID_ASSET; - } - iss_to_blind++; // If we have a reissuance, do the second blinding iteration for the inflation keys - } - - if (blind_issuance) { - for (unsigned int blind_i = 0; blind_i < iss_to_blind; ++blind_i) { - // To blind an issuance, both the issuance value and the number of inflation keys need to be blinded - // Since this process is basically the same for both, do it in a loop and switch based on the index - bool blind_value = blind_i == 0; // True for blinding the value, false for blinding the inflation keys - CAmount value = blind_value ? *input.m_issuance_value : *input.m_issuance_inflation_keys_amount; - CAsset asset = blind_value ? issuance_asset : reissuance_asset; - CKey blinding_privkey = blind_value ? our_issuances_to_blind.at(i).first : our_issuances_to_blind.at(i).second; - - uint256 value_blinder; - GetStrongRandBytes(value_blinder.begin(), value_blinder.size()); - - // Create unblinded generator. Throw away everything except asset_gen - uint256 asset_blinder; - CConfidentialAsset conf_asset; - secp256k1_generator asset_gen; - CreateAssetCommitment(conf_asset, asset_gen, asset, asset_blinder); - input_asset_blinders.push_back(asset_blinder); - - // Compute the scalar for this blinding and add to the input scalar - if (!ComputeAndAddToScalarOffset(input_scalar, value, asset_blinder, value_blinder)) return BlindingStatus::SCALAR_UNABLE; - - // Create value commitment - secp256k1_pedersen_commitment value_commit; - CConfidentialValue conf_value; - CreateValueCommitment(conf_value, value_commit, value_blinder, asset_gen, value); - - // Nonce is the blinding key - uint256 nonce = uint256(std::vector(blinding_privkey.begin(), blinding_privkey.end())); - - // Generate rangeproof - std::vector rangeproof; - bool rangeresult = CreateValueRangeProof(rangeproof, value_blinder, nonce, value, CScript(), value_commit, asset_gen, asset, asset_blinder); - assert(rangeresult); - - // Create explicit value rangeproofs - std::vector blind_value_proof; - rangeresult = CreateBlindValueProof(blind_value_proof, value_blinder, value, value_commit, asset_gen); - assert(rangeresult); - - if (blind_value) { - input.m_issuance_value_commitment = conf_value; - input.m_issuance_rangeproof = rangeproof; - input.m_blind_issuance_value_proof = blind_value_proof; - } else { - input.m_issuance_inflation_keys_commitment = conf_value; - input.m_issuance_inflation_keys_rangeproof = rangeproof; - input.m_blind_issuance_inflation_keys_proof = blind_value_proof; + if (input.m_issuance_inflation_keys_commitment.IsNull()) { + if (secp256k1_generator_generate(secp256k1_blind_context, &ephemeral_input_tags.back(), reissuance_asset.begin()) != 1) { + return BlindingStatus::INVALID_ASSET; } } - } - else { + else if(input.m_issuance_inflation_keys_commitment.IsCommitment()){ + memcpy(ephemeral_input_tags.back().data, input.m_issuance_inflation_keys_commitment.vchCommitment.data(), 33); + } input_asset_blinders.emplace_back(); } } diff --git a/src/psbt.cpp b/src/psbt.cpp index f598e5706b..69c88055fa 100644 --- a/src/psbt.cpp +++ b/src/psbt.cpp @@ -135,7 +135,7 @@ CMutableTransaction PartiallySignedTransaction::GetUnsignedTx(bool force_unblind txin.assetIssuance.nAmount.SetNull(); } if (input.m_issuance_inflation_keys_amount != std::nullopt && (input.m_issuance_inflation_keys_commitment.IsNull() || force_unblinded)) { - txin.assetIssuance.nInflationKeys.SetToAmount(*input.m_issuance_value); + txin.assetIssuance.nInflationKeys.SetToAmount(*input.m_issuance_inflation_keys_amount); } else if(!input.m_issuance_inflation_keys_commitment.IsNull()) { txin.assetIssuance.nInflationKeys = input.m_issuance_inflation_keys_commitment; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 47e936274c..87afe5a131 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1921,8 +1921,8 @@ BlindingStatus CWallet::WalletBlindPSBT(PartiallySignedTransaction& psbtx) const our_input_data[i] = std::make_tuple(amount, asset, asset_blinder, value_blinder); } - // Blind issuances on our inputs - if (input.m_issuance_value || input.m_issuance_inflation_keys_amount) { + // Blind issuances on our inputs if at least one commitment was provided. + if (input.m_issuance_value_commitment.IsCommitment() || input.m_issuance_inflation_keys_commitment.IsCommitment()) { CScript blinding_script(CScript() << OP_RETURN << std::vector(input.prev_txid.begin(), input.prev_txid.end()) << *input.prev_out); our_issuances_to_blind[i] = std::make_pair(GetBlindingKey(&blinding_script), GetBlindingKey(&blinding_script)); } From 2da7d75ee99a932ab0fe99f7d512f22ef26e89f9 Mon Sep 17 00:00:00 2001 From: Allen Piscitello Date: Wed, 24 Aug 2022 13:36:08 -0500 Subject: [PATCH 2/3] removing test that fails due to blinded issuances, which results in incorrect reissuance token ids --- test/functional/feature_sighash_rangeproof.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/functional/feature_sighash_rangeproof.py b/test/functional/feature_sighash_rangeproof.py index 0ef9d967a3..2950bbfc47 100755 --- a/test/functional/feature_sighash_rangeproof.py +++ b/test/functional/feature_sighash_rangeproof.py @@ -98,6 +98,7 @@ class SighashRangeproofTest(BitcoinTestFramework): "blind": True, # FIXME: if blind=False, `blindrawtranaction` fails. Should fix this in a future PR }] )[0]["hex"] + blinded_hex = self.nodes[1].blindrawtransaction(unsigned_hex) blinded_tx = tx_from_hex(blinded_hex) signed_hex = self.nodes[1].signrawtransactionwithwallet(blinded_hex)["hex"] @@ -164,12 +165,13 @@ class SighashRangeproofTest(BitcoinTestFramework): assert test_accept["allowed"], "not accepted: {}".format(test_accept["reject-reason"]) # Try signing using the PSBT interface - psbt_hex = self.nodes[0].converttopsbt(unsigned_hex) - signed_psbt = self.nodes[1].walletprocesspsbt(psbt_hex, True, "ALL|RANGEPROOF") - extracted_tx = self.nodes[0].finalizepsbt(signed_psbt["psbt"]) - assert extracted_tx["complete"] - test_accept = self.nodes[0].testmempoolaccept([extracted_tx["hex"]])[0] - assert test_accept["allowed"], "not accepted: {}".format(test_accept["reject-reason"]) + if not attach_issuance: # FIXME: We need to skip the issuance since the example assumes it was a blinded issuance, thus the reissuance token is incorrect. + psbt_hex = self.nodes[0].converttopsbt(unsigned_hex) + signed_psbt = self.nodes[1].walletprocesspsbt(psbt_hex, True, "ALL|RANGEPROOF") + extracted_tx = self.nodes[0].finalizepsbt(signed_psbt["psbt"]) + assert extracted_tx["complete"] + test_accept = self.nodes[0].testmempoolaccept([extracted_tx["hex"]])[0] + assert test_accept["allowed"], "not accepted: {}".format(test_accept["reject-reason"]) else: signed_tx.rehash() From dd2d758bc6a205348dcb1f2d4fd87c05160cae35 Mon Sep 17 00:00:00 2001 From: Allen Piscitello Date: Wed, 24 Aug 2022 16:31:42 -0500 Subject: [PATCH 3/3] fixed minor issues found in review --- src/blindpsbt.cpp | 82 +++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/src/blindpsbt.cpp b/src/blindpsbt.cpp index f4547041dc..c2b927e265 100644 --- a/src/blindpsbt.cpp +++ b/src/blindpsbt.cpp @@ -387,55 +387,53 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map