Skip to content

Commit 1240172

Browse files
committed
Merge #1038: PSET: Fix blinded coinjoins with 3 or more parties
3ac7e78 pset, rpc: Better error messages for imbalance failure conditions (Andrew Chow) b2a7007 pset: verify blind value and asset proofs when signing (Andrew Chow) a7ef9f3 pset, test: Test a PSET coinjoin workflow (Andrew Chow) ac580db pset, rpc: Do not fail walletprocesspsbt if missing utxos when blinding (Andrew Chow) 9f94966 pset: Allow GetUnsignedTx to force unblinded values (Andrew Chow) f9f084f pset: Add missing fields to merging and fix combinepsbt (Andrew Chow) 59f65a3 rpc, pset: Include blinded value and asset proofs in decodepsbt (Andrew Chow) 941c54f pset: Create explicit value and asset proofs during blinding (Andrew Chow) 63c007d pset: blind commitment proofs de/ser (Andrew Chow) b9a08f3 doc, pset: Add blind commitment proofs (Andrew Chow) 9856f2c pset, doc: Remove requirement to remove blinded amounts and assets (Andrew Chow) 37c925f pset: Do not remove amounts after blinding (Andrew Chow) Pull request description: In order for blinded coinjoins with 3 or more parties to work, some fields need to be added, amounts cannot be removed, and some bugs need fixing. First and foremost is to no longer remove amounts after blinding. Due to a miscommunication, I had believed that part of the goal of PSET was to hide semi private information (such as output amounts) from other parties in the transaction. However this causes the combiner to fail because the unique ID is dependent on those amounts and their commitments. If multiple parties had blinded just their own outputs, then the resulting PSETs would not combine because the amounts had be removed and so the unique ID calculated was incorrect. In order for this combining to work, amounts must be kept after blinding and the unique ID calculation must only use the computed unblinded transaction. This change has also been made to the spec document. Second is the addition of explicit value and asset proofs. In order to prove that the commitments commit to the given explicit value or asset, explicit value rangeproofs and explicit asset surjection proofs are added to PSET. Each blinded output must have an explicit value rangeproof and explict asset surjection proof after blinding. For issuances, explicit issuance value proofs and explicit reissuance value proofs must be added after blinding. These proofs are verified prior to signing. Thirdly, in order to make the coinjoin workflow work, a `blind` option is added `walletprocesspsbt` so that users can tell `walletprocesspsbt` to not attempt to blind. This is important because blinding requires all UTXOs to be present, and UTXOs can only be added via a call to `walletprocesspsbt`. Error messages have been added and improved so that users who do things in the wrong order will be less likely to end up with an unusable PSET. Lastly, a test case has been added for a 3 party coinjoin workflow. Fixes #1037 ACKs for top commit: apoelstra: ACK 3ac7e78 Tree-SHA512: b1fd848c72d8dd779b0f0640d9321b8085d62db494d25f81e3ec90e43c4a4edbe537dec404d8170a7ad057027c07f2b948980907d0849da693b2ca1bf0cf81f6
2 parents 532d55d + 3ac7e78 commit 1240172

File tree

11 files changed

+392
-66
lines changed

11 files changed

+392
-66
lines changed

doc/pset.mediawiki

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ The currently defined elements per-input proprietary types are as folows:
8484
| None
8585
| No key data
8686
| <tt><64-bit int></tt>
87-
| The explicit little endian 64-bit integer for the value of this issuance. This is mutually exclusive with <tt>PSBT_ELEMENTS_IN_ISSUANCE_VALUE_COMMITMENT</tt>
87+
| The explicit little endian 64-bit integer for the value of this issuance.
8888
|
8989
| 0
9090
| 2
@@ -94,7 +94,7 @@ The currently defined elements per-input proprietary types are as folows:
9494
| None
9595
| No key data
9696
| <tt><33 byte commitment></tt>
97-
| The 33 byte Value Commitment. This is mutually exclusive with <tt>PSBT_IN_ISSUANCE_VALUE</tt>.
97+
| The 33 byte Value Commitment. If provided, <tt>PSBT_ELEMENTS_IN_ISSUANCE_BLIND_VALUE_PROOF</tt> must be provided too.
9898
|
9999
| 0
100100
| 2
@@ -184,7 +184,7 @@ The currently defined elements per-input proprietary types are as folows:
184184
| None
185185
| No key data
186186
| <tt><64-bit int></tt>
187-
| The value for the inflation keys output to set in this issuance. This is mutually exclusive with <tt>PSBT_ELEMENTS_IN_ISSUANCE_INFLATION_KEYS</tt>.
187+
| The value for the inflation keys output to set in this issuance.
188188
|
189189
| 0
190190
| 2
@@ -194,7 +194,7 @@ The currently defined elements per-input proprietary types are as folows:
194194
| None
195195
| No key data
196196
| <tt><33 byte commitment></tt>
197-
| The 33 byte commitment to the inflation keys output value in this issuance. This is mutually exclusive with <tt>PSBT_ELEMENTS_IN_ISSUANCE_INFLATION_KEYS</tt>
197+
| The 33 byte commitment to the inflation keys output value in this issuance. If provided, <tt>PSBT_ELEMENTS_IN_ISSUANCE_BLIND_INFLATION_KEYS_PROOF</tt> must be provided too.
198198
|
199199
| 0
200200
| 2
@@ -228,6 +228,26 @@ The currently defined elements per-input proprietary types are as folows:
228228
|
229229
| 0
230230
| 2
231+
|-
232+
| Issuance Blind Value Proof
233+
| <tt>PSBT_ELEMENTS_IN_ISSUANCE_BLIND_VALUE_PROOF = 0x0f</tt>
234+
| None
235+
| No key data
236+
| <tt><rangeproof></tt>
237+
| An explicit value rangeproof that proves that the value commitment in <tt>PSBT_ELEMENTS_IN_ISSUANCE_VALUE_COMMITMENT</tt> matches the explicit value in <tt>PSBT_ELEMENTS_IN_ISSUANCE_VALUE</tt>. If provided, <tt>PSBT_ELEMENTS_IN_ISSUANCE_VALUE_COMMITMENT</tt> must be provided too.
238+
|
239+
| 0
240+
| 2
241+
|-
242+
| Issuance Inflation Keys Blind Value Proof
243+
| <tt>PSBT_ELEMENTS_IN_ISSUANCE_BLIND_INFLATION_KEYS_PROOF = 0x10</tt>
244+
| None
245+
| No key data
246+
| <tt><rangeproof></tt>
247+
| An explicit value rangeproof that proves that the value commitment in <tt>PSBT_ELEMENTS_IN_ISSUANCE_INFLATION_KEYS_COMMITMENT</tt> matches the explicit value in <tt>PSBT_ELEMENTS_IN_ISSUANCE_INFLATION_KEYS</tt>. If provided, <tt>PSBT_ELEMENTS_IN_ISSUANCE_INFLATION_KEYS_COMMITMENT</tt> must be provided too.
248+
|
249+
| 0
250+
| 2
231251
|}
232252

233253
The currently defined elements per-output proprietary types are as follows:
@@ -248,7 +268,7 @@ The currently defined elements per-output proprietary types are as follows:
248268
| None
249269
| No key data
250270
| <tt><33 byte commitment></tt>
251-
| The 33 byte Value Commitment for this output. This is mutually exclusive with <tt>PSBT_OUT_VALUE</tt>.
271+
| The 33 byte Value Commitment for this output. If provided, <tt>PSBT_ELEMENTS_OUT_BLIND_VALUE_PROOF</tt> must be provided too.
252272
|
253273
| 0
254274
| 2
@@ -258,7 +278,7 @@ The currently defined elements per-output proprietary types are as follows:
258278
| None
259279
| No key data
260280
| <tt><32 byte asset tag></tt>
261-
| The explicit 32 byte asset tag for this output. This is mutually exclusive with <tt>PSBT_ELEMENTS_OUT_ASSET_COMMITMENT</tt>.
281+
| The explicit 32 byte asset tag for this output.
262282
|
263283
| 0
264284
| 2
@@ -268,7 +288,7 @@ The currently defined elements per-output proprietary types are as follows:
268288
| None
269289
| No key data
270290
| <tt><33 byte commitment></tt>
271-
| The 33 byte Asset Commitment for this output. This is mutually exclusive with <tt>PSBT_ELEMENTS_OUT_ASSET</tt>.
291+
| The 33 byte Asset Commitment for this output. If provided, <tt>PSBT_ELEMENTS_OUT_BLIND_ASSET_PROOF</tt> must be provided too.
272292
|
273293
| 0
274294
| 2
@@ -322,10 +342,27 @@ The currently defined elements per-output proprietary types are as follows:
322342
|
323343
| 0
324344
| 2
345+
|-
346+
| Blind Value Proof
347+
| <tt>PSBT_ELEMENTS_OUT_BLIND_VALUE_PROOF = 0x09</tt>
348+
| None
349+
| No key data
350+
| <tt><rangeproof></tt>
351+
| An explicit value rangeproof that proves that the value commitment in <tt>PSBT_ELEMENTS_OUT_VALUE_COMMITMENT</tt> matches the explicit value in <tt>PSBT_OUT_VALUE</tt>. If provided, <tt>PSBT_ELEMENTS_OUT_VALUE_COMMITMENT</tt> must be provided too.
352+
|
353+
| 0
354+
| 2|-
355+
| Blind Asset Proof
356+
| <tt>PSBT_ELEMENTS_OUT_BLIND_ASSET_PROOF = 0x0a</tt>
357+
| None
358+
| No key data
359+
| <tt><proof></tt>
360+
| An asset surjection proof with this output's asset as the only asset in the input set in order to prove that the asset commitment in <tt>PSBT_ELEMENTS_OUT_ASSET_COMMITMENT</tt> matches the explicit asset in <tt>PSBT_ELEMENTS_OUT_ASSET</tt>. If provided, <tt>PSBT_ELEMENTS_OUT_ASSET_COMMITMENT</tt> must be provided too.
361+
|
362+
| 0
363+
| 2
325364
|}
326365

327-
In addition to these new types, the <tt>PSBT_OUT_AMOUNT</tt> field is no longer required so long as <tt>PSBT_ELEMENTS_OUT_VALUE_COMMITMENT</tt> is present.
328-
329366
The PSET Magic Bytes are <tt>0x70736574</tt>
330367

331368
===Handling Duplicated Keys===
@@ -373,16 +410,15 @@ A single entity is likely to be both a Creator and Updater.
373410
PSET requires a role not present in PSBT, the Blinder. Blinders are similar to Signers and own inputs.
374411
The Blinder adds the blinding data to a transaction.
375412

376-
If Bit 0 of <tt>PSBT_ELEMENTS_GLOBAL_TX_MODIFIABLE</tt> is 0, the Blinder must do nothing.
377-
378413
For issuance inputs that belong to the Blinder, the Blinder should generate a random blinding factor and create a value commitment for the issuance value.
379-
It will then add the value commitment in the <tt>PSBT_ELEMENTS_IN_ISSUANCE_VALUE_COMMITMENT</tt>. When it does so, it must remove the <tt>PSBT_ELEMENTS_IN_ISSUANCE_VALUE</tt> field.
414+
It will then add the value commitment in the <tt>PSBT_ELEMENTS_IN_ISSUANCE_VALUE_COMMITMENT</tt>.
380415
The blinder will also add the issuance value rangeproof and the issuance keys rangeproof in their respective fields.
416+
The blinder will also add the issuance blind value and issuance keys blind value proofs in their respective fields.
381417
For ease of identifying the blinder for an issuance, the input the issuance is attached to must belong to the blinder for the issuance.
382418

383419
For the Blinder's outputs that are to be blinded (i.e. they have a blinding pubkey), the Blinder will create value and asset commitments and put them in their respective fields.
384-
When they do so, the <tt>PSBT_ELEMENTS_OUT_VALUE</tt> and <tt>PSBT_ELEMENTS_OUT_ASSET</tt> fields must be removed.
385420
The Blinder will create the Value Rangeproof and Asset Surjection Proof and put them in their respective fields.
421+
The Blinder will create the blind value and blind asset proofs and put them in their respective fields.
386422
It will also add the ephemeral pubkey used for ECDH of the nonce for the rangeproof to the <tt>PSBT_ELEMENTS_OUT_ECDH_PUBKEY</tt> field.
387423

388424
The blinder will then compute a scalar offset that will be added as a <tt>PSBT_ELEMENTS_GLOBAL_SCALAR</tt>.
@@ -400,17 +436,13 @@ It will then compute a final scalar offset.
400436
Then it will subtract all of the scalar offsets from the value blinding factor for the last output and the result is the value blinding factor to be used for that last output.
401437
The creation of the commitments, proofs, and other fields proceeds as usual.
402438
Once all outputs are blinded, all <tt>PSBT_ELEMENTS_GLOBAL_SCALAR</tt> fields must be removed from the PSET.
403-
Once all outputs are blinded, Bit 0 of <tt>PSBT_ELEMENTS_GLOBAL_TX_MODIFIABLE</tt> must be set to 0.
404439
405440
A single entity is likely to be a Creator, Updater, and Blinder.
406-
In that case, the PSET should never be output with <tt>PSBT_ELEMENTS_IN_ISSUANCE_VALUE</tt>, <tt>PSBT_ELEMENTS_IN_ISSUANCE_INFLATION_KEYS</tt>, <tt>PSBT_ELEMENTS_OUT_VALUE</tt>, or <tt>PSBT_ELEMENTS_OUT_ASSET</tt> except for unblinded issuances and unblinded outputs.
407441
408442
===Signer===
409443
410444
In addition to the BIP 370 PSBT Signer behavior, PSET specifies some addtional constraints.
411445
Before signing, the Signer must check whether blinding is complete. If any output contains a blinding pubkey but no commitments or proofs, then it must not sign.
412-
This is easily done by checking whether Bit 0 of <tt>PSBT_ELEMENTS_GLOBAL_TX_MODIFIABLE</tt> is 1.
413-
If so, the Signer must do nothing.
414446
415447
===Combiner===
416448

src/blindpsbt.cpp

Lines changed: 91 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ std::string GetBlindingStatusError(const BlindingStatus& status)
2929
return "Computed blinding factor is invalid";
3030
case BlindingStatus::ASP_UNABLE:
3131
return "Unable to create an asset surjection proof";
32+
case BlindingStatus::NO_BLIND_OUTPUTS:
33+
return "Transaction has blind inputs belonging to this blinder but does not have outputs to blind";
3234
}
3335
assert(false);
3436
}
3537

3638
// Create surjection proof
37-
bool CreateAssetSurjectionProof(std::vector<unsigned char>& output_proof, const std::vector<secp256k1_fixed_asset_tag>& fixed_input_tags, const std::vector<secp256k1_generator>& ephemeral_input_tags, const std::vector<uint256>& input_asset_blinders, const uint256& output_asset_blinder, const secp256k1_generator& output_asset_tag, const CAsset& asset)
39+
bool CreateAssetSurjectionProof(std::vector<unsigned char>& output_proof, const std::vector<secp256k1_fixed_asset_tag>& fixed_input_tags, const std::vector<secp256k1_generator>& ephemeral_input_tags, const std::vector<uint256>& input_asset_blinders, const uint256& output_asset_blinder, const secp256k1_generator& output_asset_tag, const CAsset& asset, size_t num_targets)
3840
{
3941
int ret;
4042
// 1 to 3 targets
41-
size_t inputs_to_select = std::min(MAX_SURJECTION_TARGETS, fixed_input_tags.size());
43+
size_t inputs_to_select = std::min(num_targets, fixed_input_tags.size());
4244
unsigned char randseed[32];
4345
GetStrongRandBytes(randseed, 32);
4446
size_t input_index;
@@ -64,6 +66,21 @@ bool CreateAssetSurjectionProof(std::vector<unsigned char>& output_proof, const
6466
return true;
6567
}
6668

69+
bool VerifyBlindAssetProof(const std::vector<unsigned char>& proof, const CConfidentialAsset& conf_asset)
70+
{
71+
secp256k1_surjectionproof surj_proof;
72+
if (secp256k1_surjectionproof_parse(secp256k1_blind_context, &surj_proof, proof.data(), proof.size()) == 0) {
73+
return false;
74+
}
75+
76+
secp256k1_generator gen;
77+
if (secp256k1_generator_parse(secp256k1_blind_context, &gen, conf_asset.vchCommitment.data()) == 0) {
78+
return false;
79+
}
80+
81+
return secp256k1_surjectionproof_verify(secp256k1_blind_context, &surj_proof, &gen, 1, &gen) == 0;
82+
}
83+
6784
uint256 GenerateRangeproofECDHKey(CPubKey& ephemeral_pubkey, const CPubKey blinding_pubkey)
6885
{
6986
// Generate ephemeral key for ECDH nonce generation
@@ -98,6 +115,43 @@ bool CreateValueRangeProof(std::vector<unsigned char>& rangeproof, const uint256
98115
return (res == 1);
99116
}
100117

118+
// Create an explicit value rangeproof which proves that the commitment commits to an explicit value
119+
bool CreateBlindValueProof(std::vector<unsigned char>& rangeproof, const uint256& value_blinder, const CAmount amount, const secp256k1_pedersen_commitment& value_commit, const secp256k1_generator& gen)
120+
{
121+
// Prep rangeproof
122+
size_t rangeproof_len = 5134;
123+
rangeproof.resize(rangeproof_len);
124+
125+
// Generate a new random nonce
126+
uint256 nonce;
127+
GetStrongRandBytes(nonce.begin(), nonce.size());
128+
129+
// Make the rangeproof
130+
int res = secp256k1_rangeproof_sign(secp256k1_blind_context, rangeproof.data(), &rangeproof_len, /* min_value */ amount, &value_commit, value_blinder.begin(), nonce.begin(), /* exp */ -1, /* min_bits */ 0, amount, /* message */ nullptr, /* message_len */ 0, /* extra_commit */ nullptr, /* extra_commit_len */ 0, &gen);
131+
rangeproof.resize(rangeproof_len);
132+
return res == 1;
133+
}
134+
135+
bool VerifyBlindValueProof(CAmount value, const CConfidentialValue& conf_value, const std::vector<unsigned char>& proof, const CConfidentialAsset& conf_asset)
136+
{
137+
secp256k1_pedersen_commitment value_commit;
138+
if (secp256k1_pedersen_commitment_parse(secp256k1_blind_context, &value_commit, conf_value.vchCommitment.data()) == 0) {
139+
return false;
140+
}
141+
142+
secp256k1_generator gen;
143+
if (secp256k1_generator_parse(secp256k1_blind_context, &gen, conf_asset.vchCommitment.data()) == 0) {
144+
return false;
145+
}
146+
147+
uint64_t min_value;
148+
uint64_t max_value;
149+
if (secp256k1_rangeproof_verify(secp256k1_blind_context, &min_value, &max_value, &value_commit, proof.data(), proof.size(), /* extra_commit */ nullptr, /* extra_commit_len */ 0, &gen) == 0) {
150+
return false;
151+
}
152+
return min_value == (uint64_t)value;
153+
}
154+
101155
void CreateAssetCommitment(CConfidentialAsset& conf_asset, secp256k1_generator& asset_gen, const CAsset& asset, const uint256& asset_blinder)
102156
{
103157
conf_asset.vchCommitment.resize(CConfidentialAsset::nCommittedSize);
@@ -310,14 +364,19 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, st
310364
bool rangeresult = CreateValueRangeProof(rangeproof, value_blinder, nonce, value, CScript(), value_commit, asset_gen, asset, asset_blinder);
311365
assert(rangeresult);
312366

367+
// Create explicit value rangeproofs
368+
std::vector<unsigned char> blind_value_proof;
369+
rangeresult = CreateBlindValueProof(blind_value_proof, value_blinder, value, value_commit, asset_gen);
370+
assert(rangeresult);
371+
313372
if (blind_value) {
314373
input.m_issuance_value_commitment = conf_value;
315374
input.m_issuance_rangeproof = rangeproof;
316-
input.m_issuance_value = nullopt;
375+
input.m_blind_issuance_value_proof = blind_value_proof;
317376
} else {
318377
input.m_issuance_inflation_keys_commitment = conf_value;
319378
input.m_issuance_inflation_keys_rangeproof = rangeproof;
320-
input.m_issuance_inflation_keys_amount = nullopt;
379+
input.m_blind_issuance_inflation_keys_proof = blind_value_proof;
321380
}
322381
}
323382
}
@@ -327,10 +386,14 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, st
327386

328387
uint256 output_scalar;
329388
bool did_last_blind = false;
389+
int our_blinds = 0;
330390
for (uint32_t i : to_blind) {
331391
PSBTOutput& output = psbt.outputs[i];
332392

333-
if (output.IsFullyBlinded()) continue;
393+
if (output.IsFullyBlinded()) {
394+
our_blinds++;
395+
continue;
396+
}
334397

335398
// Check this is our output to blind
336399
if (output.m_blinder_index == nullopt || our_input_data.count(*output.m_blinder_index) == 0) continue;
@@ -396,30 +459,45 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, st
396459
bool rangeresult = CreateValueRangeProof(rangeproof, value_blinder, nonce, *output.amount, *output.script, value_commit, asset_generator, asset, asset_blinder);
397460
assert(rangeresult);
398461

462+
// Create explicit value rangeproof
463+
std::vector<unsigned char> blind_value_proof;
464+
rangeresult = CreateBlindValueProof(blind_value_proof, value_blinder, *output.amount, value_commit, asset_generator);
465+
assert(rangeresult);
466+
399467
// Create surjection proof for this output
400468
if (!CreateAssetSurjectionProof(asp, fixed_input_tags, ephemeral_input_tags, input_asset_blinders, asset_blinder, asset_generator, asset)) {
401469
return BlindingStatus::ASP_UNABLE;
402470
}
403471

472+
// Create explicit asset surjection proof
473+
std::vector<unsigned char> blind_asset_proof;
474+
if (!CreateAssetSurjectionProof(blind_asset_proof, fixed_input_tags, ephemeral_input_tags, input_asset_blinders, asset_blinder, asset_generator, asset, /* num_targets */ 1)) {
475+
return BlindingStatus::ASP_UNABLE;
476+
}
477+
404478
// Fill output
405479
output.m_asset_commitment = asset_commitment;
406480
output.m_value_commitment = value_commitment;
407481
output.m_ecdh_pubkey = ecdh_key;
408482
output.m_value_rangeproof = rangeproof;
409483
output.m_asset_surjection_proof = asp;
484+
output.m_blind_value_proof = blind_value_proof;
485+
output.m_blind_asset_proof = blind_asset_proof;
410486

411-
// Drop explicit value and asset
412-
output.amount = nullopt;
413-
output.m_asset.SetNull();
487+
our_blinds++;
414488
}
415489

416-
if (!did_last_blind) {
490+
// Compute scalar and add to PSBT if it isn't null
491+
if (!did_last_blind && !output_scalar.IsNull()) {
417492
// Subtract input scalar from output scalar
418493
if (!SubtractScalars(output_scalar, input_scalar)) return BlindingStatus::SCALAR_UNABLE;
419-
// Now add the scalar to the PSBT if it isn't null
420-
if (!output_scalar.IsNull()) {
421-
psbt.m_scalar_offsets.insert(output_scalar);
422-
}
494+
// Add to PSBT
495+
psbt.m_scalar_offsets.insert(output_scalar);
496+
}
497+
498+
// Make sure that we blinded some outputs if we have blinded inputs
499+
if (our_input_data.size() > 0 && our_blinds == 0) {
500+
return BlindingStatus::NO_BLIND_OUTPUTS;
423501
}
424502

425503
return BlindingStatus::OK;

src/blindpsbt.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ enum class BlindingStatus
2626
SCALAR_UNABLE,
2727
INVALID_BLINDER,
2828
ASP_UNABLE,
29+
NO_BLIND_OUTPUTS,
2930
};
3031

3132
std::string GetBlindingStatusError(const BlindingStatus& status);
3233

33-
bool CreateAssetSurjectionProof(std::vector<unsigned char>& output_proof, const std::vector<secp256k1_fixed_asset_tag>& fixed_input_tags, const std::vector<secp256k1_generator>& ephemeral_input_tags, const std::vector<uint256>& input_asset_blinders, const uint256& output_asset_blinder, const secp256k1_generator& output_asset_tag, const CAsset& asset);
34+
bool CreateAssetSurjectionProof(std::vector<unsigned char>& output_proof, const std::vector<secp256k1_fixed_asset_tag>& fixed_input_tags, const std::vector<secp256k1_generator>& ephemeral_input_tags, const std::vector<uint256>& input_asset_blinders, const uint256& output_asset_blinder, const secp256k1_generator& output_asset_tag, const CAsset& asset, size_t num_targets = MAX_SURJECTION_TARGETS);
35+
bool VerifyBlindAssetProof(const std::vector<unsigned char>& proof, const CConfidentialAsset& conf_asset);
3436
uint256 GenerateRangeproofECDHKey(CPubKey& ephemeral_pubkey, const CPubKey blinding_pubkey);
3537
bool CreateValueRangeProof(std::vector<unsigned char>& rangeproof, const uint256& value_blinder, const uint256& nonce, const CAmount amount, const CScript& scriptPubKey, const secp256k1_pedersen_commitment& value_commit, const secp256k1_generator& gen, const CAsset& asset, const uint256& asset_blinder);
38+
bool CreateBlindValueProof(std::vector<unsigned char>& rangeproof, const uint256& value_blinder, const CAmount amount, const secp256k1_pedersen_commitment& value_commit, const secp256k1_generator& gen);
39+
bool VerifyBlindValueProof(CAmount value, const CConfidentialValue& conf_value, const std::vector<unsigned char>& proof, const CConfidentialAsset& conf_asset);
3640
void CreateAssetCommitment(CConfidentialAsset& conf_asset, secp256k1_generator& asset_gen, const CAsset& asset, const uint256& asset_blinder);
3741
void CreateValueCommitment(CConfidentialValue& conf_value, secp256k1_pedersen_commitment& value_commit, const uint256& value_blinder, const secp256k1_generator& asset_gen, const CAmount amount);
3842
BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, std::tuple<CAmount, CAsset, uint256, uint256>> our_input_data, std::map<uint32_t, std::pair<CKey, CKey>> our_issuances_to_blind);

0 commit comments

Comments
 (0)