Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing PSET to not blind asset issuances by default. #1150

Merged

Conversation

allenpiscitello
Copy link
Contributor

PSET does not allow a user to specify if an issuance is to be blinded or not. The previous default was only allowing blinded, and it would blind the issuances if they were unblinded.

We should modify the PSET spec to allow specifying blinding or unblinded issuances, and in the meantime honor whatever is set in the PSET. If a commitment is set, use that, otherwise we should leave it unblinded.

Fixing this also uncovered some other minor bugs that were in previous fixes to PSET-related code.

…an option to blind or unblind issuances, defaulting to unblind.
@@ -386,7 +386,7 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, st
}

// Handle issuances
if (input.m_issuance_value) {
if (input.m_issuance_value != std::nullopt || input.m_issuance_value_commitment.IsCommitment() || input.m_issuance_inflation_keys_amount != std::nullopt || input.m_issuance_inflation_keys_commitment.IsCommitment()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous code missed cases where there was a re-issuance token but not an issuance. This is allowed, and should be accounted for.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For complex/long-winded logic checks like this, it would be nice to have methods on the input such as:

bool PSBTInput::HasIssuance() const
{
    if (m_issuance_value != std::nullopt || m_issuance_value_commitment.IsCommitment()) {
        return true; // Blinded or unblinded issuance
    }
    if (m_issuance_inflation_keys_amount != std::nullopt || m_issuance_inflation_keys_commitment.IsCommitment()) {
         return true; // Re-issuance token without an issuance
    }
    return false; // No issuance or re-issuance present
}

This would make the underlying logic much clearer IMO.

@@ -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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previous fix introduced this bug.

@@ -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) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving this logic in place even though blinding is removed, so that when the PSET spec is updated we can easily add blinding back.

memcpy(fixed_input_tags.back().data, issuance_asset.begin(), 32);
ephemeral_input_tags.emplace_back();
if (input.m_issuance_value_commitment.IsNull()) {
if (secp256k1_generator_generate(secp256k1_blind_context, &ephemeral_input_tags.back(), issuance_asset.begin()) != 1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe &ephemeral_input_tags.back() should be ephemeral_input_tags.back().data.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, no, ephemeral_input_tags.back() returns a secp256k1_generator. The real bug here is that we ever touch .data which is supposed to be a secp-zkp implementation detail, but that's a fight for another day.

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 420de43

(cannot test because of #1142)

Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not completely convinced that this is correct.

@@ -386,7 +386,7 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, st
}

// Handle issuances
if (input.m_issuance_value) {
if (input.m_issuance_value != std::nullopt || input.m_issuance_value_commitment.IsCommitment() || input.m_issuance_inflation_keys_amount != std::nullopt || input.m_issuance_inflation_keys_commitment.IsCommitment()) {
if (!input.m_issuance_value_commitment.IsCommitment() && input.m_issuance_rangeproof.size() == 0 && input.m_issuance_inflation_keys_rangeproof.size() == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entire block would be skipped if there is m_issuance_value_commitment which seems wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code for dealing with issuances/re-issuances should be same. If we are not doing it, most like a sign of bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I inspected the transaction it converted to a PSBT. The output for the reissuance token was that of the blinded reissuance token ID. This will cause a surjection proof failure because there is no input for the blinded reissuance token, only the unblinded one, when calling the PSBT version of this.


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())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are we dealing with the case m_issuance_blinding_nonce is not Null? Seems like this would not work correctly in re-issuance case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a reissuance case, there are no reissuance tokens being created, only the asset tokens. Those are handed in the section above.

@sanket1729
Copy link
Member

sanket1729 commented Aug 24, 2022

@apoelstra , @allenpiscitello. I think the following fixups would fix this. sanket1729@6182dda. Feel free to cherry-pick/squash as you see fit and if my reasoning is correct :P

  1. The bool for checking whether the re-issuance id calculation should be blinded is based only asset amount and not on issuance amount.
  2. Cleanly deals with cases where only one of issuance/re-issuance is blinded. The previous logic had some confusing checks on m_issuance_value_commitment.
  3. I think the previous case had a check on BlindingNonce being Null which could have missed the considering the confidential re-issuance outputs.

This should be easy to review if you directly compare it with validation logic in confidential_validation.cpp. Sorry if the code does not build, I do not have the machine to test building right now

@allenpiscitello
Copy link
Contributor Author

@apoelstra , @allenpiscitello. I think the following fixups would fix this. sanket1729@6182dda. Feel free to cherry-pick/squash as you see fit and if my reasoning is correct :P

  1. The bool for checking whether the re-issuance id calculation should be blinded is based only asset amount and not on issuance amount

I believe this is incorrect as stated above.

.

  1. Cleanly deals with cases where only one of issuance/re-issuance is blinded. The previous logic had some confusing checks on m_issuance_value_commitment.

The intended behavior with this modification is to just create a transaction that would not be valid if you only specified one or the other as blinded. This transaction would be invalid if you mixed and matched it.

  1. I think the previous case had a check on BlindingNonce being Null which could have missed the considering the confidential re-issuance outputs.

I believe this is wrong based on the comment above.

This should be easy to review if you directly compare it with validation logic in confidential_validation.cpp. Sorry if the code does not build, I do not have the machine to test building right now

Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK dd2d758. Thanks for putting up with the iterations. I am happy with the present logic. Part of #1126 was correctly addressed here

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK dd2d758

@psgreco psgreco merged commit 53da86e into ElementsProject:master Aug 25, 2022
apoelstra added a commit that referenced this pull request Sep 6, 2022
…or rc5

37076d7 Bump version to -rc5 (Pablo Greco)
5629cae fs: Make compatible with boost 1.78 (Andrew Chow)
60b913e Elements-qt: Correctly display the amount in the sender's wallet after using Send button (Andrea Bonel)
872478b docs: describe elements transaction serialization format (#1148) (James Dorfman)
dd2d758 fixed minor issues found in review (Allen Piscitello)
2da7d75 removing test that fails due to blinded issuances, which results in incorrect reissuance token ids (Allen Piscitello)
420de43 removing code to blind issuances. PSET should be modified to include an option to blind or unblind issuances, defaulting to unblind. (Allen Piscitello)

Pull request description:

  Backport #1150 #1154 and #1148 from master.
  Backport bitcoin/bitcoin#24104 from Bitcoin Core
  Bump to -rc5

ACKs for top commit:
  jamesdorfman:
    utACK 37076d7.
  delta1:
    utACK 37076d7

Tree-SHA512: 616322f94c17008cc7fd582203c22b33c73b922269ab33fd13b270f491eda9b30d4f18efa3f7887e247bef46b63c4810f4084e409bea98120702c426a83343a8
gwillen added a commit to gwillen/elements that referenced this pull request Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants