Skip to content

Commit c4d5a2e

Browse files
committed
Merge branch 'master' into elements-22-fix-ci
2 parents 519d4a8 + f49e97d commit c4d5a2e

10 files changed

+260
-20
lines changed

.cirrus.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ task:
160160
<< : *GLOBAL_TASK_TEMPLATE
161161
container:
162162
image: ubuntu:focal
163-
cpu: 4 # Increase CPU and memory to avoid timeout
163+
cpu: 8 # Increase CPU and memory to avoid timeout
164164
memory: 16G
165165
env:
166166
<< : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV

doc/elements-tx-format.md

+13-13
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ This document assumes some familiarity with Bitcoin and Elements (UTXOs, [Script
2121
| Flags | Yes | 1 byte | `unsigned char` | | 1 if the transaction contains a witness, otherwise 0. All other values are invalid. |
2222
| Num Inputs | Yes | Varies | `VarInt` | | Number of inputs to the transaction. |
2323
| Inputs | Yes | Varies | `Vector<TxIn>` | | |
24-
| Num Inputs | Yes | Varies | `VarInt` | | Number of outputs from the transaction. |
24+
| Num Outputs | Yes | Varies | `VarInt` | | Number of outputs from the transaction. |
2525
| Outputs | Yes | Varies | `Vector<TxOut>` | | |
2626
| Locktime | Yes | 4 bytes | `uint32_t` | Little-endian | See [BIP 113](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki). |
2727
| Witness | Only if flags is 1 | Varies | `Witness` | | See [BIP 141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki). Note that Elements witnesses contain more data than Bitcoin witnesses. This extra data is described further below. |
@@ -203,13 +203,13 @@ Deserialization:
203203
| Input #2
204204
| 8d83eb1b0826f46d473003d041116927
205205
| 470e2ce0f7cc0c634a983d438d770ac8 ... Outpoint TXID: c80a778d433d984a630cccf7e02c0e4727691141d00330476df426081beb838d
206-
| 00000000 ........................... Outpoint index
206+
| 00000000 ........................... Outpoint index
207207
|
208208
| 00 ................................. ScriptSig length
209209
| | .................................. ScriptSig (empty)
210210
|
211211
| ffffffff ........................... Sequence number: UINT32_MAX
212-
212+
213213
02 ................................... Num Outputs
214214
|
215215
| Output #1
@@ -239,7 +239,7 @@ Deserialization:
239239
| 03 ................................. Nonce header (0x03 → compressed point)
240240
| 72fdd5c6e805a50d73ab15ec41cfaadc
241241
| be408ecc7a5867621918f1070f84ec95 ... Nonce x-coordinate (big-endian)
242-
|
242+
|
243243
| 16 ................................. ScriptPubKey length (0x16 = 22 bytes)
244244
| | 001424ae71d4804ca7dd1fa66486a8
245245
| | 7af9dff1663c84 ................... ScriptPubKey
@@ -317,18 +317,18 @@ Deserialization:
317317
| | .................................. ScriptSig (empty: segwit transaction)
318318
|
319319
| fdffffff ........................... Sequence number
320-
|
320+
|
321321
| .................................... Asset issuance
322322
| | 000000000000000000000000000000
323323
| | 000000000000000000000000000000
324324
| | 0000 ............................. Asset blinding nonce (0 for new asset issuance)
325-
| |
325+
| |
326326
| | 000000000000000000000000000000
327327
| | 000000000000000000000000000000
328328
| | 0000 ............................. Asset entropy
329329
| |
330330
| | 01 ............................... Amount header (0x01 → explicit, unblinded value)
331-
| | 00000000c4b20100 ................. Amount: 0xc4b20100 = 3,300,000,000 → 33 units (each divisible by 100,000,000)
331+
| | 00000000c4b20100 ................. Amount: 0xc4b20100 = 3,300,000,000 → 33 units (each divisible by 100,000,000)
332332
| |
333333
| | 01 ............................... Num inflation keys header (0x01 → explicit, unblinded value)
334334
| | 0000000029b92700 ................. Value. 0x29b92700 = 700,000,000 inflation keys
@@ -343,7 +343,7 @@ Deserialization:
343343
| 08 ................................. Amount header (0x08 → blinded value)
344344
| 66abe471dfadfb650825abe6f757860b
345345
| 6760d30ff62bc7c9ebd438608f45368b ... Amount x-coordinate (big-endian)
346-
|
346+
|
347347
| 02 ................................. Nonce header (0x02 → blinded value)
348348
| 115750003261bc64bb73d83401a91279
349349
| 6d0c0fb9d54c72751a7ca7a5149a9bdf ... Nonce x-coordinate (big-endian)
@@ -518,7 +518,7 @@ Deserialization:
518518
| 6d521c38ec1ea15734ae22b7c4606441
519519
| 2829c0d0579f0a713d1c04ede979026f ... Asset ID: 6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d
520520
|
521-
| 01 ................................. Amount header (0x01 → explicit, unblinded value)
521+
| 01 ................................. Amount header (0x01 → explicit, unblinded value)
522522
| 00000000002b09c1 ................... Amount: 0.02820545 L-BTC
523523
|
524524
| 00 ................................. Nonce header (0x00 → null)
@@ -532,7 +532,7 @@ Deserialization:
532532
| 6d521c38ec1ea15734ae22b7c4606441
533533
| 2829c0d0579f0a713d1c04ede979026f ... Asset ID: 6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d
534534
|
535-
| 01 ................................. Amount header (0x01 → explicit, unblinded value)
535+
| 01 ................................. Amount header (0x01 → explicit, unblinded value)
536536
| 0000000000000027 ................... Amount: 0.00000039 L-BTC
537537
|
538538
| 00 ................................. Nonce header (0x00 → null)
@@ -560,10 +560,10 @@ Deserialization:
560560
| | | f34227cbba1cf25eb0778aa45f8b
561561
| | | 7cb3495046 ..................... Stack item #2
562562
| 06 ................................. Peg-in witness stack length
563-
| | 08 ............................... Stack item #1 length
563+
| | 08 ............................... Stack item #1 length
564564
| | | e8092b0000000000 ............... Peg-in value (little-endian): 0x2b09e8 = 0.02820545 BTC)
565565
| | 20 ............................... Stack item #2 length (0x20 = 32)
566-
| | | 6d521c38ec1ea15734ae22b7c46064
566+
| | | 6d521c38ec1ea15734ae22b7c46064
567567
| | | 412829c0d0579f0a713d1c04ede979
568568
| | | 026f ........................... Asset ID: 6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d
569569
| | 20 ............................... Stack item #3 length (0x20 = 32)
@@ -592,4 +592,4 @@ Deserialization:
592592
| Output #2 witness
593593
| 00 ................................. Surjection proof length
594594
| 00 ................................. Range proof length
595-
```
595+
```

doc/pset.mediawiki

+50
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,56 @@ The currently defined elements per-input proprietary types are as follows:
255255
|
256256
| 0
257257
| 2
258+
|-
259+
| Explicit Value
260+
| <tt>PSBT_ELEMENTS_IN_EXPLICIT_VALUE = 0x11</tt>
261+
| None
262+
| No key data
263+
| <tt><64-bit little endian int value></tt>
264+
| The explicit value for the input being spent. If provided, <tt>PSBT_ELEMENTS_IN_VALUE_PROOF</tt> must be provided too. Must not be provided if the input's value in the UTXO is already explicit.
265+
|
266+
| 0
267+
| 2
268+
|-
269+
| Explicit Value Proof
270+
| <tt>PSBT_ELEMENTS_IN_VALUE_PROOF = 0x12</tt>
271+
| None
272+
| No key data
273+
| <tt><rangeproof></tt>
274+
| An explicit value rangeproof that proves that the value commitment in this input's UTXO matches the explicit value in <tt>PSBT_ELEMENTS_IN_EXPLICIT_VALUE</tt>. If provided, <tt>PSBT_ELEMENTS_IN_EXPLICIT_VALUE</tt> must be provided too.
275+
|
276+
| 0
277+
| 2
278+
|-
279+
| Explicit Asset
280+
| <tt>PSBT_ELEMENTS_IN_EXPLICIT_ASSET = 0x13</tt>
281+
| None
282+
| No key data
283+
| <tt><32 byte asset tag></tt>
284+
| The explicit asset for the input being spent. If provided, <tt>PSBT_ELEMENTS_IN_ASSET_PROOF</tt> must be provided too. Must not be provided if the input's asset in the UTXO is already explicit.
285+
|
286+
| 0
287+
| 2
288+
|-
289+
| Explicit Asset Proof
290+
| <tt>PSBT_ELEMENTS_IN_ASSET_PROOF = 0x14</tt>
291+
| None
292+
| No key data
293+
| <tt><proof></tt>
294+
| An asset surjection proof with this input's asset as the only asset in the input set in order to prove that the asset commitment in the UTXO matches the explicit asset in <tt>PSBT_ELEMENTS_IN_EXPLICIT_ASSET</tt>. If provided, <tt>PSBT_ELEMENTS_IN_EXPLICIT_ASSET</tt> must be provided too.
295+
|
296+
| 0
297+
| 2
298+
|-
299+
| Blinded Issuance Flag
300+
| <tt>PSBT_ELEMENTS_IN_BLINDED_ISSUANCE = 0x15</tt>
301+
| None
302+
| No key data
303+
| <tt><1 byte boolean></tt>
304+
| A boolean flag. <tt>0x00</tt> indicates the issuance should not be blinded, <tt>0x01</tt> indicates it should be. If not specified, assumed to be <tt>0x01</tt>. Note that this does not indicate actual blinding status, but rather the expected blinding status prior to signing.
305+
|
306+
| 0
307+
| 2
258308
|}
259309

260310
The currently defined elements per-output proprietary types are as follows:

share/setup.nsi.in

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Var StartMenuGroup
5252
!insertmacro MUI_LANGUAGE English
5353

5454
# Installer attributes
55-
InstallDir $PROGRAMFILES64\Bitcoin
55+
InstallDir $PROGRAMFILES64\Elements
5656
CRCCheck on
5757
XPStyle on
5858
BrandingText " "
@@ -105,7 +105,7 @@ Section -post SEC0001
105105
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
106106
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
107107
WriteRegStr HKCR "@PACKAGE_TARNAME@" "URL Protocol" ""
108-
WriteRegStr HKCR "@PACKAGE_TARNAME@" "" "URL:Bitcoin"
108+
WriteRegStr HKCR "@PACKAGE_TARNAME@" "" "URL:Elements"
109109
WriteRegStr HKCR "@PACKAGE_TARNAME@\DefaultIcon" "" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@
110110
WriteRegStr HKCR "@PACKAGE_TARNAME@\shell\open\command" "" '"$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "%1"'
111111
SectionEnd
@@ -138,7 +138,7 @@ Section -un.post UNSEC0001
138138
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk"
139139
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk"
140140
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, 64-bit).lnk"
141-
Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk"
141+
Delete /REBOOTOK "$SMSTARTUP\Elements.lnk"
142142
Delete /REBOOTOK $INSTDIR\uninstall.exe
143143
Delete /REBOOTOK $INSTDIR\debug.log
144144
Delete /REBOOTOK $INSTDIR\db.log

src/blindpsbt.cpp

+31-1
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,35 @@ BlindProofResult VerifyBlindProofs(const PSBTOutput& o) {
220220
return BlindProofResult::OK;
221221
}
222222

223+
BlindProofResult VerifyBlindProofs(const PSBTInput& i) {
224+
CTxOut utxo;
225+
if (!i.GetUTXO(utxo)) {
226+
return BlindProofResult::OK;
227+
}
228+
229+
if (i.m_explicit_value != std::nullopt) {
230+
if (i.m_value_proof.empty()) {
231+
return BlindProofResult::MISSING_VALUE_PROOF;
232+
} else if (!utxo.nValue.IsCommitment()) {
233+
return BlindProofResult::NOT_FULLY_BLINDED;
234+
} else if (!VerifyBlindValueProof(*i.m_explicit_value, utxo.nValue, i.m_value_proof, utxo.nAsset)) {
235+
return BlindProofResult::INVALID_VALUE_PROOF;
236+
}
237+
}
238+
239+
if (!i.m_explicit_asset.IsNull()) {
240+
if (i.m_asset_proof.empty()) {
241+
return BlindProofResult::MISSING_ASSET_PROOF;
242+
} else if (!utxo.nAsset.IsCommitment()) {
243+
return BlindProofResult::NOT_FULLY_BLINDED;
244+
} else if (!VerifyBlindAssetProof(i.m_explicit_asset, i.m_asset_proof, utxo.nAsset)) {
245+
return BlindProofResult::INVALID_ASSET_PROOF;
246+
}
247+
}
248+
249+
return BlindProofResult::OK;
250+
}
251+
223252
void CreateAssetCommitment(CConfidentialAsset& conf_asset, secp256k1_generator& asset_gen, const CAsset& asset, const uint256& asset_blinder)
224253
{
225254
conf_asset.vchCommitment.resize(CConfidentialAsset::nCommittedSize);
@@ -386,7 +415,8 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, st
386415
}
387416

388417
// Handle issuances
389-
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()) {
418+
if ((!input.m_blinded_issuance.has_value() || input.m_blinded_issuance.value()) &&
419+
(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())) {
390420
CAsset issuance_asset;
391421
CAsset reissuance_asset;
392422

src/blindpsbt.h

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
struct PartiallySignedTransaction;
1919
struct PSBTOutput;
20+
struct PSBTInput;
2021

2122
enum class BlindingStatus
2223
{
@@ -52,5 +53,6 @@ BlindingStatus BlindPSBT(PartiallySignedTransaction& psbt, std::map<uint32_t, st
5253
bool VerifyBlindValueProof(CAmount value, const CConfidentialValue& conf_value, const std::vector<unsigned char>& proof, const CConfidentialAsset& conf_asset);
5354
bool VerifyBlindAssetProof(const uint256& asset, const std::vector<unsigned char>& proof, const CConfidentialAsset& conf_asset);
5455
BlindProofResult VerifyBlindProofs(const PSBTOutput& o);
56+
BlindProofResult VerifyBlindProofs(const PSBTInput& i);
5557

5658
#endif //BITCOIN_BLINDPSBT_H

src/psbt.h

+95
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ static constexpr uint8_t PSBT_ELEMENTS_IN_ISSUANCE_ASSET_ENTROPY = 0x0d;
7373
static constexpr uint8_t PSBT_ELEMENTS_IN_UTXO_RANGEPROOF = 0x0e;
7474
static constexpr uint8_t PSBT_ELEMENTS_IN_ISSUANCE_BLIND_VALUE_PROOF = 0x0f;
7575
static constexpr uint8_t PSBT_ELEMENTS_IN_ISSUANCE_BLIND_INFLATION_KEYS_PROOF = 0x10;
76+
static constexpr uint8_t PSBT_ELEMENTS_IN_EXPLICIT_VALUE = 0x11;
77+
static constexpr uint8_t PSBT_ELEMENTS_IN_VALUE_PROOF = 0x12;
78+
static constexpr uint8_t PSBT_ELEMENTS_IN_EXPLICIT_ASSET = 0x13;
79+
static constexpr uint8_t PSBT_ELEMENTS_IN_ASSET_PROOF = 0x14;
80+
static constexpr uint8_t PSBT_ELEMENTS_IN_BLINDED_ISSUANCE = 0x15;
7681

7782
// Output types
7883
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
@@ -248,6 +253,7 @@ struct PSBTInput
248253
uint256 m_issuance_asset_entropy;
249254
std::vector<unsigned char> m_blind_issuance_value_proof;
250255
std::vector<unsigned char> m_blind_issuance_inflation_keys_proof;
256+
std::optional<bool> m_blinded_issuance;
251257

252258
// Peg-in
253259
std::variant<std::monostate, Sidechain::Bitcoin::CTransactionRef, CTransactionRef> m_peg_in_tx;
@@ -259,6 +265,10 @@ struct PSBTInput
259265

260266
// Auxiliary elements stuff
261267
std::vector<unsigned char> m_utxo_rangeproof;
268+
std::optional<CAmount> m_explicit_value;
269+
std::vector<unsigned char> m_value_proof;
270+
uint256 m_explicit_asset;
271+
std::vector<unsigned char> m_asset_proof;
262272

263273
bool IsNull() const;
264274
void FillSignatureData(SignatureData& sigdata) const;
@@ -473,6 +483,31 @@ struct PSBTInput
473483
SerializeToVector(s, CompactSizeWriter(PSBT_OUT_PROPRIETARY), PSBT_ELEMENTS_ID, CompactSizeWriter(PSBT_ELEMENTS_IN_ISSUANCE_BLIND_INFLATION_KEYS_PROOF));
474484
s << m_blind_issuance_inflation_keys_proof;
475485
}
486+
487+
// Explicit value and its proof
488+
if (m_explicit_value.has_value()) {
489+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_PROPRIETARY), PSBT_ELEMENTS_ID, CompactSizeWriter(PSBT_ELEMENTS_IN_EXPLICIT_VALUE));
490+
SerializeToVector(s, m_explicit_value.value());
491+
}
492+
if (!m_value_proof.empty()) {
493+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_PROPRIETARY), PSBT_ELEMENTS_ID, CompactSizeWriter(PSBT_ELEMENTS_IN_VALUE_PROOF));
494+
s << m_value_proof;
495+
}
496+
497+
// Explicit asset and its proof
498+
if (!m_explicit_asset.IsNull()) {
499+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_PROPRIETARY), PSBT_ELEMENTS_ID, CompactSizeWriter(PSBT_ELEMENTS_IN_EXPLICIT_ASSET));
500+
SerializeToVector(s, m_explicit_asset);
501+
}
502+
if (!m_asset_proof.empty()) {
503+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_PROPRIETARY), PSBT_ELEMENTS_ID, CompactSizeWriter(PSBT_ELEMENTS_IN_ASSET_PROOF));
504+
s << m_asset_proof;
505+
}
506+
507+
if (m_blinded_issuance.has_value()) {
508+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_PROPRIETARY), PSBT_ELEMENTS_ID, CompactSizeWriter(PSBT_ELEMENTS_IN_BLINDED_ISSUANCE));
509+
SerializeToVector(s, *m_blinded_issuance);
510+
}
476511
}
477512

478513
// Write proprietary things
@@ -886,6 +921,60 @@ struct PSBTInput
886921
s >> m_blind_issuance_inflation_keys_proof;
887922
break;
888923
}
924+
case PSBT_ELEMENTS_IN_EXPLICIT_VALUE:
925+
{
926+
if (!key_lookup.emplace(key).second) {
927+
throw std::ios_base::failure("Duplicate Key, explicit value is already provided");
928+
} else if (subkey_len != 1) {
929+
throw std::ios_base::failure("Input explicit value is more than one byte type");
930+
}
931+
CAmount v;
932+
UnserializeFromVector(s, v);
933+
m_explicit_value = v;
934+
break;
935+
}
936+
case PSBT_ELEMENTS_IN_VALUE_PROOF:
937+
{
938+
if (!key_lookup.emplace(key).second) {
939+
throw std::ios_base::failure("Duplicate Key, explicit value proof is already provided");
940+
} else if (subkey_len != 1) {
941+
throw std::ios_base::failure("Input explicit value proof is more than one byte type");
942+
}
943+
s >> m_value_proof;
944+
break;
945+
}
946+
case PSBT_ELEMENTS_IN_EXPLICIT_ASSET:
947+
{
948+
if (!key_lookup.emplace(key).second) {
949+
throw std::ios_base::failure("Duplicate Key, explicit asset is already provided");
950+
} else if (subkey_len != 1) {
951+
throw std::ios_base::failure("Input explicit asset is more than one byte type");
952+
}
953+
UnserializeFromVector(s, m_explicit_asset);
954+
break;
955+
}
956+
case PSBT_ELEMENTS_IN_ASSET_PROOF:
957+
{
958+
if (!key_lookup.emplace(key).second) {
959+
throw std::ios_base::failure("Duplicate Key, explicit asset proof is already provided");
960+
} else if (subkey_len != 1) {
961+
throw std::ios_base::failure("Input explicit asset proof is more than one byte type");
962+
}
963+
s >> m_asset_proof;
964+
break;
965+
}
966+
case PSBT_ELEMENTS_IN_BLINDED_ISSUANCE:
967+
{
968+
if (!key_lookup.emplace(key).second) {
969+
throw std::ios_base::failure("Duplicate Key, issuance needs blinded flag is already provided");
970+
} else if (subkey_len != 1) {
971+
throw std::ios_base::failure("Input issuance needs blinded flag is more than one byte type");
972+
}
973+
bool b;
974+
UnserializeFromVector(s, b);
975+
m_blinded_issuance = b;
976+
break;
977+
}
889978
default:
890979
{
891980
known = false;
@@ -936,6 +1025,12 @@ struct PSBTInput
9361025
if (!m_issuance_inflation_keys_commitment.IsNull() && m_issuance_inflation_keys_rangeproof.empty()) {
9371026
throw std::ios_base::failure("Issuance inflation keys commitment provided without inflation keys rangeproof");
9381027
}
1028+
if ((m_explicit_value.has_value() || !m_value_proof.empty()) && (!m_explicit_value.has_value() || m_value_proof.empty())) {
1029+
throw std::ios_base::failure("Input explicit value and value proof must be provided together");
1030+
}
1031+
if ((!m_explicit_asset.IsNull() || !m_asset_proof.empty()) && (m_explicit_asset.IsNull() || m_asset_proof.empty())) {
1032+
throw std::ios_base::failure("Input explicit asset and asset proof must be provided together");
1033+
}
9391034
}
9401035
}
9411036

0 commit comments

Comments
 (0)