-
Notifications
You must be signed in to change notification settings - Fork 375
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This entire block would be skipped if there is There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
CAsset issuance_asset; | ||
CAsset reissuance_asset; | ||
|
@@ -400,83 +400,40 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, st | |
GenerateAssetEntropy(entropy, input.GetOutPoint(), input.m_issuance_asset_entropy); | ||
} | ||
|
||
// Asset isn't blinded yet. Add it to the list of input assets | ||
CalculateAsset(issuance_asset, entropy); | ||
fixed_input_tags.emplace_back(); | ||
memcpy(fixed_input_tags.back().data, issuance_asset.begin(), 32); | ||
ephemeral_input_tags.emplace_back(); | ||
if (secp256k1_generator_generate(secp256k1_blind_context, &ephemeral_input_tags.back(), issuance_asset.begin()) != 1) { | ||
return BlindingStatus::INVALID_ASSET; | ||
if (input.m_issuance_value != std::nullopt || input.m_issuance_value_commitment.IsCommitment()) { | ||
// Asset isn't blinded yet. Add it to the list of input assets | ||
CalculateAsset(issuance_asset, entropy); | ||
fixed_input_tags.emplace_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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, no, |
||
return BlindingStatus::INVALID_ASSET; | ||
} | ||
} | ||
else { | ||
memcpy(ephemeral_input_tags.back().data, input.m_issuance_value_commitment.vchCommitment.data(), 33); | ||
} | ||
input_asset_blinders.emplace_back(); | ||
} | ||
unsigned int iss_to_blind = 1; // Always do the first issuance blinding iteration for the issuance value | ||
|
||
bool blind_issuance = our_issuances_to_blind.count(i) > 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())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where are we dealing with the case There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
// 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<unsigned char>(blinding_privkey.begin(), blinding_privkey.end())); | ||
|
||
// Generate rangeproof | ||
std::vector<unsigned char> 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<unsigned char> 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(); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previous fix introduced this bug. |
||
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; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
// 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<unsigned char>(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)); | ||
} | ||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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:
This would make the underlying logic much clearer IMO.