From 0d1fac536f975af81523e536846f6e37f86688c1 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 18 Jan 2017 14:48:00 -0800 Subject: [PATCH 01/31] Update the Sidechain creation guide for `refresh` --- source/sidechains/creating-your-own.md | 260 ++++++++++--------------- 1 file changed, 105 insertions(+), 155 deletions(-) diff --git a/source/sidechains/creating-your-own.md b/source/sidechains/creating-your-own.md index 4dabdf8..4f12ffb 100644 --- a/source/sidechains/creating-your-own.md +++ b/source/sidechains/creating-your-own.md @@ -3,162 +3,112 @@ title: Building A New Sidechain with Elements edit: https://github.com/ElementsProject/elementsproject.github.io/blob/master/source/sidechains/creating-your-own.md source: https://github.com/ElementsProject/elementsproject.github.io/edit/master/source/sidechains/creating-your-own.md --- -This is a basic step-by-step guide to building your own sidechain and setting up -a federated peg mechanism. This configuration works to run a sidechain with -a 1-of-1 functionary/blocksigner. (Not tested on multiple nodes with more than 1 -signer). -There are several other ways of deriving consensus on a sidechain. See [the Deterministic Peg Element](/elements/deterministic-peg.html) for more details. +This is step-by-step guide will walk you through building your own sidechain and +setting up a simple single-signer peg with a `regtest`-powered mainchain. This +configuration works to run a sidechain with a 1-of-1 functionary/blocksigner, +convenient for local development and testing. -#### Elements -Please look over [the Elements -Git Repository](https://github.com/ElementsProject/elements), if you haven't already. -Also read [Alpha -README](https://github.com/ElementsProject/elements/blob/alpha/alpha-README.md) -for building dependencies and to follow along. The instructions for building the -dependencies are pretty cut and clear, however, the building of a new fedpeg -isn't as detailed. Keep the Elements Project's Alpha-README open in a separate -tab for reference. +There are several other ways of deriving consensus on a sidechain. See [the +Deterministic Peg Element](/elements/deterministic-peg.html) for more details. #### Prerequisites -1. *Linux.* Building with Windows is possible - publish a guide if you know how as there isn't one publicly available! :) -2. *All dependencies for Elements Alpha.* See [Build Notes](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md) - -#### Build -Try to follow this order to avoid unneccessary recompilations. This is an extension of the instructions to "Run a fedpeg operator" in the Element's alpha README. - -Edit your `.bashrc`. We'll come back to this file later: -```shell -RPC_USER=your_username_here -RPC_PASSWORD=your_super_random_long_password_here -export RPC_USER -export RPC_PASS -``` - -Build bitcoin (mainchain): -```shell -git clone https://github.com/ElementsProject/elements -cd elements -git checkout mainchain -./autogen.sh && ./configure && make -mv src/bitcoin{d,-cli,-tx} ../ -``` - -Run testnet. If you get an error asking to rebuild the blockchain, replace `-txindex` with `-reindex`. If you have to rebuild it, continue these instructions while it syncs: -```shell -./bitcoind -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS -testnet -txindex -daemon -``` - -Checkout the `alpha` branch. -```shell -git checkout alpha -``` - -With bitcoin testnet, generate an address and obtain the private/public key. -``` -bitcoin-cli -testnet getnewaddress -//returns some address -bitcoin-cli -testnet dumpprivkey [address] -//returns private key. Save this - we'll need it later for .bashrc file -bitcoin-cli -testnet validateaddress [address] -//returns JSON object. Copy the public key. -``` - -#### C++ -You should be on your sidechain branch (alpha). This is the part where we uniquely create your sidechain with the public keys of each functionary/blocksigner. Open `src/chainparams.cpp` and edit the public keys, ports, and seeds. [Line 132](https://github.com/ElementsProject/elements/blob/alpha/src/chainparams.cpp#L132) has the public keys for each functionary/blocksigner: -```c++ -scriptDestination = CScript() << OP_5 - << ParseHex("027d5d62861df77fc9a37dbe901a579d686d1423be5f56d6fc50bb9de3480871d1") - << ParseHex("03b41ea6ba73b94c901fdd43e782aaf70016cc124b72a086e77f6e9f4f942ca9bb") - << ParseHex("02be643c3350bade7c96f6f28d1750af2ef507bc1f08dd38f82749214ab90d9037") - << ParseHex("021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a") - << ParseHex("0320ea4fcf77b63e89094e681a5bd50355900bf961c10c9c82876cb3238979c0ed") - << ParseHex("021c4c92c8380659eb567b497b936b274424662909e1ffebc603672ed8433f4aa1") - << ParseHex("027841250cfadc06c603da8bc58f6cd91e62f369826c8718eb6bd114601dd0c5ac") - << OP_7 << OP_CHECKMULTISIG; -``` - -For simplicity, let's replace the current 5-of-7 multisig with a 1-of-1. Change to: -```c++ -scriptDestination = CScript() << OP_1 - << ParseHex("[paste public key we just generated]") - << OP_1 << OP_CHECKMULTISIG; -``` -[Line 139](https://github.com/ElementsProject/elements/blob/alpha/src/chainparams.cpp#L139) has the DNS seeds. If you have more than 1 functionary/blocksigner, you'll need to create a DNS of your own in order to communicate. Replace the current 5 seeds with the seeds of your signers. Also delete the testnet seed on [L198](https://github.com/ElementsProject/elements/blob/alpha/src/chainparams.cpp#L198). If you're creating a local 1-of-1 sidechain on your machine that won't be communicating on any port, you don't need to create any seeds or configure the protocol port. - -Still in `src/chainparams.cpp`, change the testnet port number on [L182](https://github.com/ElementsProject/elements/blob/alpha/src/chainparams.cpp#L182) - this is the unique channel of communication for your sidechain so don't just increase/decrease it by one. This is one of two ports we'll change. Call this one the protocol port. - -You need to duplicate what you did on L132 of `src/chainparams.cpp` on [L1451](https://github.com/ElementsProject/elements/blob/alpha/src/script/interpreter.cpp#L1451) of `src/script/interpreter.cpp`. -Replace this line -```c++ -CScript scriptDestination(CScript() << OP_5 - << ParseHex("0269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d933") - << ParseHex("021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a") - << ParseHex("02174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea1") - << ParseHex("033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a") - << ParseHex("0313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c2") - << ParseHex("030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab0") - << ParseHex("02fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce") - << OP_7 << OP_CHECKMULTISIG); -``` -with - -```c++ -CScript scriptDestination(CScript() << OP_1 - << ParseHex("[paste public key we just generated]") - << OP_1 << OP_CHECKMULTISIG); -``` - -Open `src/chainparamsbase.cpp`, change the port on [L43](https://github.com/ElementsProject/elements/blob/alpha/src/chainparamsbase.cpp#L43). This is the RPC port - keep it different from the protocol port (i.e. alpha's ports are 4241 and 4242). On L44 of the same file, you can change the name of the data directory for your sidechain (where your blocks, .dat files, etc. will be stored). - -At this point, you can compile your sidechain in the same way we compiled the mainchain earlier. There are a few help/console string messages you can change in `main.cpp, init.cpp, bitcoind.cpp`, but it's not necessary for basic functional purposes. - -```shell -./autogen.sh && ./configure && make -``` - -If there's a error in your compilation, go back to the file the compilation failed on and fix the error. Make sure to run `make clean` before compilating again. You'll only need to recompile your sidechain branch, not the bitcoin testnet `mainchain` branch. - -Upon successful compilation: -```shell -mv src/alpha{d,-cli,-tx} ../ -./alphad -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS -testnet -rpcconnect=127.0.0.1 -rpcconnectport=18332 -tracksidechain=all -txindex -blindtrust=false -daemon -``` - -####Python - -Once your sidechain server is running, we can edit the Python files with your unique details. - -Inside `contrib/fedpeg/constants.py`, change the port number on [L9](https://github.com/TomMcCabe/elements/blob/patch/contrib/fedpeg/constants.py) to the port number you specified above inside of your [src/chainparamsbase.cpp](https://github.com/ElementsProject/elements/blob/alpha/src/chainparamsbase.cpp#L43). You do NOT change the `bitcoin_url` port. - -We need to create a unique `redeem_script` and `redeem_script_address` for your sidechain. To do this, take the public key[s] in `chainparams.cpp` and use the `createmultisig` RPC, which will return an address and a redeem script. Adjust [L12-L13](https://github.com/Christewart/elements/blob/sidechain/contrib/fedpeg/constants.py#L12-L13) in `constants.py` with the values given by the following RPC command: - -```shell -alpha-cli -testnet createmultisig [sigs_required] "[\"public key\", ...]" -``` - -You can test this by decoding the redeem script (`alpha-cli -testnet decodescript [redeem script])`, which will return a JSON object with the public keys, signatures required and P2SH address. - -Replace the `nodes` with the network addresses (i.e. IPs) of your sidechain's blocksigners/functionaries. Add your network address to `my_node`. - -Open the `.bashrc` file we edited earlier and add this to the bottom: - -```shell -BLOCKSIGNING_PRIV_KEY=[private key generated earlier - associated to the public key in chainparmas.cpp] -FUNCTIONARY_PRIV_KEY=[some separate generated private key] -export BLOCKSIGNING_PRIV_KEY -export FUNCTIONARY_PRIV_KEY -``` - -Also be sure to import both private keys into your sidechain wallet using the RPC command: - -```shell -alpha-cli -testnet importprivkey [private key] -``` - -The default sidechain blocktimes are set at 60 seconds. You can adjust the time on [L58](https://github.com/ElementsProject/elements/blob/alpha/contrib/fedpeg/blocksign.py#L58) of `contrib/fedpeg/blocksign.py`. Be sure to change the port number in [blocksign.py](https://github.com/ElementsProject/elements/blob/alpha/contrib/fedpeg/blocksign.py#L14) if you have multiple functionaries/blocksigners. - -From here, you can follow [Step 6](https://github.com/ElementsProject/elements/blob/alpha/alpha-README.md#to-move-money-into-elements-alpha) of the Elements-Alpha README to move money into the sidechain. After the "claim-on-sidechain" part, run `blocksign.py` to run the blocksigning script(remember you can shorten block times): -```shell -./contrib/fedpeg/blocksign.py -``` +You'll need a working version of Elements. Follow [the Elements build +instructions](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md) +to get set up. + +### Creating your own blockchain +Just like in Bitcoin, Elements can be started in `regtest` mode which allows to +easily create test chains and networks. + +1. Start Elements: + > `elementsd -regtest -daemon` +2. Create an alias for the RPC client: + > `alias bc="elements-cli -regtest"` +
+ In Elements, blocks have to be signed by a quorum of the federation. However, just like in Bitcoin the conditions in regtest modes are not enforced, so you can simply create a block with `bc generate 1`. +
+3. Create a chain where we predetermine who is allowed to sign blocks. We start with creating a fresh keypair. + > ADDR=`bc getnewaddress` + > PUBKEY=`bc validateaddress $ADDR | jq -r '.pubkey'` + > PRIVKEY=`bc dumpprivkey $ADDR` +4. Create a 1-of-1 multisig script to use as a block requirement. + > SIGNBLOCKSCRIPT=`bc createmultisig 1 \[\"$PUBKEY\"\] | jq -r '.redeemScript'` +5. Stop the daemon and create a new chain using the blocksigner script + > bc stop + > rm -rf ~/.bitcoin/elementsregtest + > elementsd -regtest -daemon -signblockscript=$SIGNBLOCKSCRIPT + > bc importprivkey $PRIVKEY + > NEW_BLOCK=`bc getnewblockhex` + > BLOCKSIG=`bc signblock $NEW_BLOCK` +
+ If there were multiple blocksigners, you'd need to distribute `NEW_BLOCK`, collect signatures, then call `combineblocksigs`. We'll leave this as an excercise to the reader. +
+ > SIGNED_BLOCK=`bc combineblocksigs $NEW_BLOCK \[\"$BLOCKSIG\"\] | jq -r '.hex'` + * ensure that the output of combineblocksigs has "complete" true + > `bc getblockcount` + * check the current block count + > `bc submitblock $SIGNED_BLOCK` + > `bc getblockcount` + * check that the chain advanced by one block + +Block generation can be easily automated in a shell script. + +#### Congratulations! +Your chain is online and already accessible, just let other nodes connect to you: +``` +bc addnode +``` + +### Moving Bitcoin into your Sidechain +You might have figured out that while you are in `regtest` mode you own all +coins on the elements chain. Of course, in production you first have to use a +mechanism known as peg-in to move coins from the main chain to the elements +sidechain. Let's set up our own sidechain federation to handle the peg. + +1. Ensure that you have bitcoind 0.13.1 installed and elements as well as bitcoin are shut down. +2. Elements fully validates that peg-in transactions exists in Bitcoin. Therefore, it opens a RPC connection to bitcoind and checks that a particular block is in the chain and has the required confirmations. We need to ensure that the elements daemon is correctly talking to Bitcoin. + * The configuration of Elements is getting larger, so we best create a config file in a new data directory. + * `BETADATADIR=/tmp/elementsdatadir/` + * `mkdir $BETADATADIR` + * Put the following into $BETADATADIR/elements.conf + ``` + rpcuser=bitcoinrpc + rpcpassword=password + rpcport=8339 + daemon=1 + discover=0 + testnet=0 + regtest=1 + + mainchainrpchost=127.0.0.1 + mainchainrpcport=8338 + mainchainrpcuser=bitcoinrpc + mainchainrpcpassword=password + + validatepegin=1 + txindex=1 + ``` + * Now do the same for bitcoin + * `BITCOINDATADIR=/tmp/bitcoindatadir/` + * `mkdir $BITCOINDATADIR` + * put the following into $BITCOINDATADIR/bitcoin.conf + ``` + rpcuser=bitcoinrpc + rpcpassword=password + rpcport=8338 + daemon=1 + discover=0 + testnet=0 + regtest=1 + txindex=1 + ``` +* In the previous section we've used our own public key for the blocksigner script. We will use the same for the federation script. This is the script that owns the coins on the sidechain. +* Let's start bitcoin `bitcoind -datadir=$BITCOINDATADIR` and elements `elementsd -datadir=$BETADATADIR -signblockscript=$SIGNBLOCKSCRIPT -fedpegscript=$SIGNBLOCKSCRIPT` +* Let's update the elements-cli alias to use the new datadir + * `alias bc="elements-cli -datadir=$BETADATADIR"` + * `alias bitc="bitcoin-cli -datadir=$BITCOINDATADIR"` +* Create some coins on the main chain + * `bitc generate 101` +* We can't create a regular peg-in yet, because there are no WPV outputs in regtest mode. We first create them by `sendtomainchain `. Note that peg-outs don't work, because you have no pegoutwatcher running. +* Now you can perform the regular peg-in steps, by first calling `getpeginaddress` on elements then sending coins with bitcoin, then -- again on elements -- claiming coins with `claimpegin`. Ensure that both chains are mining all the time. From 42069d04daef4677ba831bc87fca427dfba1a052 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Fri, 10 Mar 2017 04:06:29 -0800 Subject: [PATCH 02/31] Begin integration of CT docs --- package.json | 4 +- .../confidential-transactions/index.md | 522 ++++++------------ .../investigation.md | 356 ++++++++++++ 3 files changed, 519 insertions(+), 363 deletions(-) create mode 100644 source/elements/confidential-transactions/investigation.md diff --git a/package.json b/package.json index 0737afe..ada1887 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "start": "hexo server" }, "hexo": { - "version": "3.2.0" + "version": "3.2.2" }, "dependencies": { "hexo": "^3.1.0", @@ -31,4 +31,4 @@ "type": "git", "url": "git+https://github.com/ElementsProject/elementsproject.org.git" } -} +} \ No newline at end of file diff --git a/source/elements/confidential-transactions/index.md b/source/elements/confidential-transactions/index.md index 6759042..9c7c2b4 100644 --- a/source/elements/confidential-transactions/index.md +++ b/source/elements/confidential-transactions/index.md @@ -7,8 +7,8 @@ edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/s --- One of the most powerful new features being explored in Elements is Confidential -Transactions. This keeps the amounts transferred visible only to participants in -the transaction (and those they designate), while still guaranteeing that no +Transactions. This keeps the amounts transferred visible only to participants +in the transaction (and those they designate), while still guaranteeing that no more coins can be spent than are available in a cryptographic way. This goes a step beyond the usual privacy offered by Bitcoin's blockchain, which @@ -19,369 +19,169 @@ protection, thieves and scammers can focus their efforts on known high-value targets, competitors can learn business details, and negotiating positions can be undermined. -The most visible implication of Confidential Transactions is the introduction of -a new address type, [confidential -addresses](/confidential-transactions/addresses). These are longer than usual as -they also includes a blinding key for the values. Several sidechains, including -[alpha](/sidechains/alpha), use this address type as the default. - -### Designated Access -By sharing the blinding key used in the construction of a single confidential -transaction, users can share access to the details of an individual transaction. - ---- - -### Investigation -*Principal Investigator: [Gregory Maxwell](/contributors/gmaxwell)* - -The security of the Bitcoin ledger is made possible by universal verification: -each participant individually and autonomously verifies that each transaction is -valid, without trusting any third party. An unfortunate side effect is that all -the transaction data must be conspicuously public so it can be verified, which -is at odds with the normal expectation of privacy for traditional monetary -instruments. - -Insufficient financial privacy can have serious security and privacy -implications for both commercial and personal transactions. Without adequate -protection, thieves and scammers can focus their efforts on known high-value -targets, competitors can learn business details, and negotiating positions can -be undermined. Since publishing often requires spending money, lack of privacy -can chill free speech. Insufficient privacy can also result in a loss of -fungibility--where some coins are treated as more acceptable than others--which -would further undermine Bitcoin's utility as money. - -Bitcoin partially addresses the privacy problem by using pseudonymous -addresses. If someone does not know which users own which addresses, -the privacy impact is reduced. But any time you transact with someone -you learn at least one of their addresses. From there, you can trace out -other connected addresses and estimate the values of their transactions -and holdings. For example, suppose your employer pays you with Bitcoin -and you later spend those coins on your rent and groceries. Your landlord -and the supermarket will both learn your income, and could charge you -higher prices as your income changes or target you for theft. - -There are existing deployed techniques that further improve privacy -in Bitcoin (such as CoinJoin, which merges the transaction history of -users by making joint payments), but the utility of these techniques is -reduced by the fact that it's possible to track amounts. - -There have been proposed cryptographic techniques to improve privacy -in Bitcoin-like systems, but so far all of them result in breaking -"pruning" (section 7 of Bitcoin.pdf) and result in participants -needing a perpetually growing database to verify new transactions, -because these systems prevent learning which coins have been spent. Most -proposed cryptographic privacy systems also have poor performance, high -overhead, and/or require new and very strong (and less well understood) -cryptographic assumptions. - -Confidential Transactions improves the situation by making the transaction -amounts private, while preserving the ability of the public network -to verify that the ledger entries still add up. It does this without -adding any new basic cryptographic assumptions to the Bitcoin system, -and with a manageable level of overhead. - -CT is possible due to the cryptographic technique of additively -homomorphic commitments. As a side-effect of its design, CT also enables -the additional exchange of private "memo" data (such as invoice numbers -or refund addresses) without any further increase in transaction size, -by reclaiming most of the overhead of the CT cryptographic proofs. - - -## The technology behind Confidential Transactions: A high level technical primer - - -This work was originally proposed by Adam Back on -Bitcointalk in his 2013 thread "[bitcoins with homomorphic value] -(https://bitcointalk.org/index.php?topic=305791.0)". To build CT I had to -implement several new cryptosystems which work in concert, and invented -a generalization of ring signatures and several novel optimizations to -make the result reasonably efficient. - -The basic tool that CT is based on is a Pedersen commitment. - -A commitment scheme lets you keep a piece of data secret but commit to -it so that you cannot change it later. A simple commitment scheme can -be constructed using a cryptographic hash: - -``` -commitment = SHA256( blinding_factor || data ) -``` - -If you tell someone only the commitment then they cannot determine -what data you are committing to (given certain assumptions about the -properties of the hash), but you can later reveal both the data and the -blinding factor and they can run the hash and verify that the data you -committed to matches. The blinding factor is present because without one, -someone could try guessing at the data; if your data is small and simple, -it might be easy to just guess it and compare the guess to the commitment. - -A Pedersen commitment works like the above but with an additional -property: commitments can be added, and the sum of a set of commitments -is the same as a commitment to the sum of the data (with a blinding key -set as the sum of the blinding keys): - -``` -C(BF1, data1) + C(BF2, data2) == C(BF1 + BF2, data1 + data2) -C(BF1, data1) - C(BF1, data1) == 0 -``` - -In other words, the commitment preserves addition and the commutative -property applies. - -If data_n = {1,1,2} and BF_n = {5,10,15} then: - -``` -C(BF1, data1) + C(BF2, data2) - C(BF3, data3) == 0 -``` - -and so on. - -Our specific Pedersen commitments are constructed using elliptic curve -points. [The reader need not understand elliptic curve cryptography, -beyond accepting the black box behaviors I describe here.] - -Normally an ECC pubkey is created by multiplying a generator for the group -(G) with the secret key (x): - -``` -Pub = xG -``` - -The result is usually serialized as a 33-byte array. - -ECC public keys obey the additively homomorphic property mentioned before: - -``` -Pub1 + Pub2 = (x1 + x2 (mod n))G. -``` - -(This fact is used by the BIP32 HD wallet scheme to allow third parties -to generate fresh Bitcoin addresses for people.) - -The Pedersen commitment is created by picking an additional generator -for the group (which we'll call H) such that no one knows the discrete -log for H with respect to G (or vice versa), meaning no one knows an -x such that xG = H. We can accomplish this by using the cryptographic -hash of G to pick H: - -``` -H = to_point(SHA256(ENCODE(G))) -``` - -Given our two generators we can build a commitment scheme like this: - -``` -commitment = xG + aH -``` - -Here x is our secret blinding factor, and a is the amount that we're -committing to. You can verify just using the commutative property of -addition that all the relationships given for an additively homomorphic -commitment scheme hold. - -The Pedersen commitments are information-theoretically private: for any -commitment you see, there exists some blinding factor which would make -any amount match the commitment. Even an attacker with infinite computing -power could not tell what amount you committed to, if your blinding factor -was truly random. They are computationally secure against fake commitment, -in that you can't actually compute that arbitrary mapping; if you can -it means you can find the discrete log of the generators with respect -to each other, which means that the security of the group is compromised. - -With this tool in hand we can go and replace the normal 8-byte integer -amounts in Bitcoin transactions with 33-byte Pedersen commitments. - -If the author of a transaction takes care in picking their blinding -factors so that they add up correctly, then the network can still verify -the transaction by checking that its commitments add up to zero: - -``` -(In1 + In2 + In3 + plaintext_input_amount*H...) - - (Out1 + Out2 + Out3 + ... fees*H) == 0. -``` - -This requires making the fees in a transaction explicit, but that's -generally desirable. - -The commitment and its checking are quite simple. Unfortunately, without -additional measures this scheme is insecure. - -The problem is that the group is cyclic, and addition is mod P (a 256-bit -prime number that defines the order of the group). As a result, an addition -of large values can 'overflow' and behave like negative amounts. This -means that a sums-to-zero behavior still holds when some outputs are -negative, effectively allowing the creation of 5 coins from nothing: - -``` -(1 + 1) - (-5 + 7) == 0 -``` - -This would be interpreted as "someone spends two bitcoins, gets a '-5' -bitcoin out that they discard out, and a 7 bitcoin output". - -In order to prevent this, when there are multiple outputs we must prove -that each committed output is within a range which cannot overflow -(e.g. [0, 2^64)). - -We could just disclose the amounts and blinding factors so that the -network could check, but this would lose all of the privacy. So, -instead, we need to prove that a committed amount is within the range -but reveal nothing else about it: we need an additional cryptosystem -to prove the range of a Pedersen commitment. We use a scheme similar -to Schoenmakers' binary decomposition but with many optimizations -(including not using binary). - -To build this we start with a basic EC signature. If a signature is -constructed so that the 'message' is the hash of the pubkey, the signature -proves that the signer knew the private key, which is the discrete log -of the pubkey with respect to some generator. - -For a 'pubkey' like P = xG + aH, no one knows the discrete log of P -with respect to G because of the addition of H, because no one knows -an x for xG = H----_unless_ a is 0. If a is zero then P = xG and the -discrete log is just x; someone could sign for that pubkey. - -A pedersen commitment can be proven to be a commitment to a zero by -just signing a hash of the commitment with the commitment as the public -key. Using the public key in the signature is required to prevent setting -the signature to arbitrary values and solving for the commitment. The -private key used for the signature is just the blinding factor. - -Going further, let's say I want to prove C is a commitment to 1 without -telling you the blinding factor. All you do is compute - -``` -C' = C - 1H -``` - -and ask me to provide a signature (with respect to G) with pubkey C'. If -I can do that, the C must be a commitment to 1 (or else I've broken the -EC discrete log security). +
+

Did you know?

+

By sharing the blinding key used in the construction of a single confidential transaction, users can share access to the transaction's details.

+
-To avoid giving away the amount we need yet another cryptographic -construct: a ring signature. A ring signature is a signature scheme -where there are two (or more) pubkeys and the signature proves that the -signer knows the discrete log of at least one of the pubkeys. - -So with that we can construct a scheme where I prove a commitment that -C is either 0 or 1--we call this an "OR proof". - -First, I give you C, and you compute C': +#### In Practice +The payment flow when using the Confidential Transactions Element is nearly +identical to Bitcoin Core on the surface: ``` -C' = C - 1H -``` - - -Then I provide a ring signature over {C, C'}. - -If C was a commitment to 1 then I do not know its discrete log, but -C' becomes a commitment to 0 and I do know its discrete log (just the -blinding factor). If C was a commitment to 0 I know its discrete log, -and I don't for C'. If it was a commitment to any other amount, none -of the result will be zero and I won't be able to sign. - -This works for any pair of numbers, just by suitably pre-processing the -amounts that are put into the ring... or even for more than two numbers. +elements-cli getnewaddress +XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq -Say I want to prove to you that C is in the range [0, 32). Now that we -have an OR proof, imagine I send you a collection of commitments and OR -proofs for each of them: - -``` -C1 is 0 or 1 C2 is 0 or 2 C3 is 0 or 4 C4 is 0 or 8 C5 is 0 or 16. +elements-cli sendtoaddress XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq 0.005 +82b2c5122207e5f33e7adadc6a4aab16a170e16028f0b0cf2c04f9d17d6f0321 ``` -If I pick the blinding factors for C1..5 correctly then I can arrange -it so that C1 + C2 + C3 + C4 + C5 == C. Effectively I have built up -the number in binary, and a 5-bit number can only be in the range [0,32). - -Numerous optimizations are required to make this more efficient: - -First, I propose a new ring -signature formulation, a Borromean ring signature[*](https://github.com/Blockstream/borromean_paper/raw/master/borromean_draft_0.01_34241bb.pdf), which is especially -efficient: it requires only 32 bytes per pubkey, plus 32 bytes which -can be shared by many separate rings. This is has twice the asymptotic -efficiency of previously proposed constructions for this application. - -Instead of expressing the amount directly, CT amounts are expressed -using a decimal floating point where the digits are multiplied by a -base 10 exponent. This means that you can prove large amounts with -small proofs, so long as they have few significant digits in base 10: -e.g., 11.2345 and .0112345 can have the same size proof, even though -one number is a thousand times larger. - -There is also a non-private "minimum amount" sent, which allows a smaller -proof to cover a larger range if the user doesn't mind leaking some -information about the minimum amount (which might already be public for -external reasons); this also allows the least significant digits to be -non-zero when an exponent is used. Minimum amounts are supported by first -subtracting the minimum, then proving that the result is non-negative. +The key difference from Bitcoin is the addition of cryptographic privacy. These +transactions differ in that the the amounts transferred are kept visible only to +participants in the transaction (and those they designate). -The mantissa of the floating point is encoded using rings of size 4 (base -4) rather than binary, because this minimizes the number of commitments -sent while not using any more signature data than base 2. - -The final mantissa digit commitment can be skipped, backwards constructing -it from the value being proven and the other digits, etc. - -Finally, by careful use of derandomized signing in the prover, it's -possible for the receiver of the coins--who shares a secret with the -sender, due to ECDH key agreement with the receivers pubkey--to 'rewind' -the proof and use it to extract a message sent by the sender which is 80% -of the size of the proof. We use this to signal the value and blinding -factor to the receiver, but it could also be used to carry things like -reference numbers or refund addresses. - -The result is that a proof for a 32-bit value is 2564 bytes, and -simultaneously may convey 2048 bytes of message. A 32-bit proof can -cover a range of 42.94967296 BTC with 1e-8 precision, or 429.4967296 -BTC with 1e-7 precision, and so on. My implementation is able to verify -over 1300 32-bit range proofs per second on an i7-4770R, and there are -many performance optimizations still possible. - -The implementation supports proofs of any mantissa size or exponent, with -the parameters controlled by the sender. Performance and size are linear -in the number of mantissa bits, and odd numbers of bits are supported -(by switching to radix-2 for the last digit). - -In Elements, the range proofs are only required in cases where there are -multiple confidential value outputs (including fees). Transactions that -merge multiple confidential amounts into a single output do not need range -proofs since the fact that all the inputs were in range is sufficient. - -By sharing the scanning key used to establish the shared secret used by -the rewindable range proofs, this approach is completely compatible with -watching wallets; users can share these keys with auditors to enable -them to view their transaction amounts. - -Future work may use the fact that proofs can support a minimum value to -also allow skipping the range proofs when there is a single confidential -output even when fees are being paid, or allow nodes to skip or delay -verifying most range proofs by using fraud proofs. - -The system presented here depends on no new fundamental cryptographic -assumptions, only the hardness of the discrete log problem in the -secp256k1 group and a random oracle assumption, just like the normal -signatures in Bitcoin. - -While the size of the range proofs are non-trivial, they are still an -order of magnitude smaller and faster to verify than some alternatives -(like Zerocoin), and most of their space can be reclaimed to communicate -additional data between users, a feature which is often requested but -hard to justify in a public broadcast network. Similar to signatures, -the range proofs can be placed on separate tree branches in blocks to -allow clients that don't care about (e.g. historical ones) to skip -receiving them. - -Most importantly, this scheme is compatible with pruning and does not make -the verification state for Bitcoin grow forever. It is also compatible -with CoinJoin and CoinSwap, allowing for transaction graph privacy as -well while simultaneously fixing the most severe limitation of these -approaches to privacy (that transaction amounts compromise their privacy). - -Unlike some other proposals, this system is not just speculation or pure -cryptography without integration with the Bitcoin system. - -Confidential Transactions is enabled in Elements and used by default by -all ordinary transactions. +#### Confidential Addresses +The most visible implication of Confidential Transactions is the introduction of +a new default address type, confidential addresses: + +``` +XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq +``` + +The most obvious differences are that it starts with ``XoR`` and is longer than +usual. This is due to the inclusion of a public blinding key prepended to the +base address. In the Liquid wallet the blinding key is derived by using the +wallet's master blinding key and unblinded P2PKH address. Therefore the receiver +alone can decrypt the sent amount, and can hand it to auditors if needed. On the +sender's side, ``sendtoaddress`` will use this pubkey to transmit the necessary +info to the receiver, encrypted, and inside the transaction itself. The sender's +wallet will also record the amount and hold this in the ``wallet.dat`` metadata +as well as the ``audit.log`` file. + +``` +elements-cli validateaddress XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq +{ + "isvalid": true, + "address": "XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq", + "scriptPubKey": "76a91448a67bbdaf57b6f55b50f02fcaacfa079900853588ac", + "confidential_key": "02483237addc73befdb9b851f948c1488cbb7cf1a59ba8af36be1c479e0f6e8bc7", + "unconfidential": "QTE8CaT6FcJEqkCR4ZGdoUJfas57eDqY6q", + "ismine": true, + "iswatchonly": false, + "isscript": false, + "pubkey": "0347b013d415f7dc964cfadd0bb0627c48ae6ae27a58cdd37d71990eaf8f38c60c", + "iscompressed": true, + "account": "" +} +``` + +As you can see the unconfidential P2PKH address starts with a `Q`. P2SH start +with `H`. Most RPC calls outside of ``getnewaddress`` (e.g., ``listunspent``) +will return the unblinded version of addresses. If you provide an unconfidential +address to ``validateaddress`` it will show the confidential address. + +You **must** use the confidential address in ``sendtoaddress``, ``sendfrom``, +``sendmany`` and ``createrawtransaction`` if you want to create confidential +transactions. Therefore, when you want to receive confidential transactions you +must give the *confidential* address to the sender. For all other RPC's except +``dumpblindingkey`` it does not matter whether the confidential or +unconfidential address is provided. + +In order to execute a third-party audit of transaction amounts, the blinding key +can be exported by the receiver and passed on to the auditor. + +``` +elements-cli dumpblindingkey XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq +5fd02f714d52b68bbbfef3b8e6d83be646fad1de5150e83d26a28496e00a2146 +``` + +The auditor may then import the address and blinding key with +``importblindingkey`` to observe watch-only amounts. + +``` +elements-cli importaddress XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq +elements-cli listtransactions "*" 1 0 true +[ +] +elements-cli importblindingkey XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq 5fd02f714d52b68bbbfef3b8e6d83be646fad1de5150e83d26a28496e00a2146 +elements-cli listtransactions "*" 1 0 true +[ + { + "involvesWatchonly": true, + "account": "", + "address": "QTE8CaT6FcJEqkCR4ZGdoUJfas57eDqY6q", + "category": "receive", + "amount": 0.00500000, + "label": "", + "vout": 1, + "confirmations": 35, + "blockhash": "708f969b4fb1c705b82fa3ed309abc7a3d9b0e87aa6e5d17542bb7ee04c8e1f1", + "blockindex": 1, + "blocktime": 1488223140, + "txid": "82b2c5122207e5f33e7adadc6a4aab16a170e16028f0b0cf2c04f9d17d6f0321", + "walletconflicts": [ + ], + "time": 1488223140, + "timereceived": 1488225018, + "bip125-replaceable": "no", + "blindingfactors": "0000000000000000000000000000000000000000000000000000000000000000:71260137a80039dd8cee330d9f7bba625697dc53098cf54d625242946f26997b:" + } +] +``` + +The ``createrawtransaction`` API in Liquid works similar to Bitcoin's raw +transactions with the following differences: + +1. The intent to create a confidential output is indicated by using a confidential address for the destination. +2. The ``createrawtransaction`` RPC has the additional key ``nValue`` per input which must be set to the value of the input. The value can be determined for example with the ``listunspent`` RPC. +3. After calling ``createrawtransaction`` the user must call ``blindrawtransaction`` on the transaction if a confidential input or output address is involved. +4. If at least one of the inputs is confidential, at least one of the outputs must be confidential. Note that it is perfectly fine to create a 0-valued confidential output if otherwise there would be no confidential output. +5. If all inputs are unconfidential, the number of confidential outputs must be ``0`` or ``>= 2``. Again, it's fine to create a 0-valued confidential output. + +The following example spends a confidential and an unconfidential output and +creates a confidential and unconfidential output. Due to the size of the +transaction it is not displayed here but saved in the variable ``TX`` + +``` +TX=`elements-cli createrawtransaction '[{"txid": "421079661b117b659af3431096ce2118043396e3647e523e413cd626fa798df7", "vout": 0, "nValue": 0.001}, {"txid": "17aa26d29582a9a26f02033918aaf9823d33458239074a0d7ee638b247f1fa2c", "vout": 0, "nValue": 0.001}]' '{"XoRDiv9z12ECsYCNjtHjDvV1Nn4KSBa6xRfHT1c3nKY1CwDiz5rzSMZL7QCgvuF1T5Kq43o1fMqBxbWQ": 0.001, "QLsHc5DgnpMjPaDSuEF5gXt7ccgmLtgh2N": 0.0005}'` +TX=`elements-cli blindrawtransaction $TX` +TX=`elements-cli signrawtransaction $TX | jq -r '.hex'` +elements-cli sendrawtransaction $TX +``` + +### Limitations +The implementation of Confidential Transactions in Liquid has some important +limitations to be aware of. The CT implementation only hides a certain number of +the digits of the amount of each transaction output. The exact numeric limits +will be set once the production Liquid network is ready, but they will work as +follows: There will be a 'minimum confidential amount' that will be a round +number of BTC, probably around 0.0001 BTC. There will be a 'maximum confidential +amount' that will be 232 times the minimum amount, probably around +500,000 BTC. + +Digits smaller than the minimum will be revealed to observers; for example, if +the minimum is 0.0001 BTC, a transaction output of 123.456789 BTC will look like +"?.????89 BTC". The tiny amount of information about the value leaked in this +way is unlikely to be important, but be aware that this could allow observers to +'follow' coins by linking subsequent transactions with identical amounts. All +values can be rounded to the minimum to avoid revealing information in this way +if preferred. + +A transaction output larger than the maximum will reveal the order of magnitude +of the amount to observers, AND will reveal additional digits at the bottom of +the amount. (Technical details: The minimum amount will effectively be 'raised' +such that 232 times the new minimum is large enough to cover the +transaction.) + +For example, if the maximum is 500k BTC, then all outputs under +that amount will look the same, but an output between 500k and 5M BTC will be +visible as such to observers (but not the exact amount within that range), and +will also reveal one additional digit of the low end of the amount. Revealing +the range in this way could be a very significant privacy leak; splitting such +extremely large transactions to keep them under the maximum confidential amount +is strongly recommended. + +
+

Want to learn more?

+

Gregory Maxwell's original investigation into Confidential Transactions has the mathy details!

+
diff --git a/source/elements/confidential-transactions/investigation.md b/source/elements/confidential-transactions/investigation.md new file mode 100644 index 0000000..fb54a5d --- /dev/null +++ b/source/elements/confidential-transactions/investigation.md @@ -0,0 +1,356 @@ +### Investigation +Principal Investigator: [Gregory Maxwell](/contributors/gmaxwell) + +The security of the Bitcoin ledger is made possible by universal verification: +each participant individually and autonomously verifies that each transaction is +valid, without trusting any third party. An unfortunate side effect is that all +the transaction data must be conspicuously public so it can be verified, which +is at odds with the normal expectation of privacy for traditional monetary +instruments. + +Insufficient financial privacy can have serious security and privacy +implications for both commercial and personal transactions. Without adequate +protection, thieves and scammers can focus their efforts on known high-value +targets, competitors can learn business details, and negotiating positions can +be undermined. Since publishing often requires spending money, lack of privacy +can chill free speech. Insufficient privacy can also result in a loss of +fungibility--where some coins are treated as more acceptable than others--which +would further undermine Bitcoin's utility as money. + +Bitcoin partially addresses the privacy problem by using pseudonymous +addresses. If someone does not know which users own which addresses, +the privacy impact is reduced. But any time you transact with someone +you learn at least one of their addresses. From there, you can trace out +other connected addresses and estimate the values of their transactions +and holdings. For example, suppose your employer pays you with Bitcoin +and you later spend those coins on your rent and groceries. Your landlord +and the supermarket will both learn your income, and could charge you +higher prices as your income changes or target you for theft. + +There are existing deployed techniques that further improve privacy +in Bitcoin (such as CoinJoin, which merges the transaction history of +users by making joint payments), but the utility of these techniques is +reduced by the fact that it's possible to track amounts. + +There have been proposed cryptographic techniques to improve privacy +in Bitcoin-like systems, but so far all of them result in breaking +"pruning" (section 7 of Bitcoin.pdf) and result in participants +needing a perpetually growing database to verify new transactions, +because these systems prevent learning which coins have been spent. Most +proposed cryptographic privacy systems also have poor performance, high +overhead, and/or require new and very strong (and less well understood) +cryptographic assumptions. + +Confidential Transactions improves the situation by making the transaction +amounts private, while preserving the ability of the public network +to verify that the ledger entries still add up. It does this without +adding any new basic cryptographic assumptions to the Bitcoin system, +and with a manageable level of overhead. + +CT is possible due to the cryptographic technique of additively +homomorphic commitments. As a side-effect of its design, CT also enables +the additional exchange of private "memo" data (such as invoice numbers +or refund addresses) without any further increase in transaction size, +by reclaiming most of the overhead of the CT cryptographic proofs. + + +## The technology behind Confidential Transactions: A high level technical primer + + +This work was originally proposed by Adam Back on +Bitcointalk in his 2013 thread "[bitcoins with homomorphic value] +(https://bitcointalk.org/index.php?topic=305791.0)". To build CT I had to +implement several new cryptosystems which work in concert, and invented +a generalization of ring signatures and several novel optimizations to +make the result reasonably efficient. + +The basic tool that CT is based on is a Pedersen commitment. + +A commitment scheme lets you keep a piece of data secret but commit to +it so that you cannot change it later. A simple commitment scheme can +be constructed using a cryptographic hash: + +``` +commitment = SHA256( blinding_factor || data ) +``` + +If you tell someone only the commitment then they cannot determine +what data you are committing to (given certain assumptions about the +properties of the hash), but you can later reveal both the data and the +blinding factor and they can run the hash and verify that the data you +committed to matches. The blinding factor is present because without one, +someone could try guessing at the data; if your data is small and simple, +it might be easy to just guess it and compare the guess to the commitment. + +A Pedersen commitment works like the above but with an additional +property: commitments can be added, and the sum of a set of commitments +is the same as a commitment to the sum of the data (with a blinding key +set as the sum of the blinding keys): + +``` +C(BF1, data1) + C(BF2, data2) == C(BF1 + BF2, data1 + data2) +C(BF1, data1) - C(BF1, data1) == 0 +``` + +In other words, the commitment preserves addition and the commutative +property applies. + +If data_n = {1,1,2} and BF_n = {5,10,15} then: + +``` +C(BF1, data1) + C(BF2, data2) - C(BF3, data3) == 0 +``` + +and so on. + +Our specific Pedersen commitments are constructed using elliptic curve +points. [The reader need not understand elliptic curve cryptography, +beyond accepting the black box behaviors I describe here.] + +Normally an ECC pubkey is created by multiplying a generator for the group +(G) with the secret key (x): + +``` +Pub = xG +``` + +The result is usually serialized as a 33-byte array. + +ECC public keys obey the additively homomorphic property mentioned before: + +``` +Pub1 + Pub2 = (x1 + x2 (mod n))G. +``` + +(This fact is used by the BIP32 HD wallet scheme to allow third parties +to generate fresh Bitcoin addresses for people.) + +The Pedersen commitment is created by picking an additional generator +for the group (which we'll call H) such that no one knows the discrete +log for H with respect to G (or vice versa), meaning no one knows an +x such that xG = H. We can accomplish this by using the cryptographic +hash of G to pick H: + +``` +H = to_point(SHA256(ENCODE(G))) +``` + +Given our two generators we can build a commitment scheme like this: + +``` +commitment = xG + aH +``` + +Here x is our secret blinding factor, and a is the amount that we're +committing to. You can verify just using the commutative property of +addition that all the relationships given for an additively homomorphic +commitment scheme hold. + +The Pedersen commitments are information-theoretically private: for any +commitment you see, there exists some blinding factor which would make +any amount match the commitment. Even an attacker with infinite computing +power could not tell what amount you committed to, if your blinding factor +was truly random. They are computationally secure against fake commitment, +in that you can't actually compute that arbitrary mapping; if you can +it means you can find the discrete log of the generators with respect +to each other, which means that the security of the group is compromised. + +With this tool in hand we can go and replace the normal 8-byte integer +amounts in Bitcoin transactions with 33-byte Pedersen commitments. + +If the author of a transaction takes care in picking their blinding +factors so that they add up correctly, then the network can still verify +the transaction by checking that its commitments add up to zero: + +``` +(In1 + In2 + In3 + plaintext_input_amount*H...) - + (Out1 + Out2 + Out3 + ... fees*H) == 0. +``` + +This requires making the fees in a transaction explicit, but that's +generally desirable. + +The commitment and its checking are quite simple. Unfortunately, without +additional measures this scheme is insecure. + +The problem is that the group is cyclic, and addition is mod P (a 256-bit +prime number that defines the order of the group). As a result, an addition +of large values can 'overflow' and behave like negative amounts. This +means that a sums-to-zero behavior still holds when some outputs are +negative, effectively allowing the creation of 5 coins from nothing: + +``` +(1 + 1) - (-5 + 7) == 0 +``` + +This would be interpreted as "someone spends two bitcoins, gets a '-5' +bitcoin out that they discard out, and a 7 bitcoin output". + +In order to prevent this, when there are multiple outputs we must prove +that each committed output is within a range which cannot overflow +(e.g. [0, 2^64)). + +We could just disclose the amounts and blinding factors so that the +network could check, but this would lose all of the privacy. So, +instead, we need to prove that a committed amount is within the range +but reveal nothing else about it: we need an additional cryptosystem +to prove the range of a Pedersen commitment. We use a scheme similar +to Schoenmakers' binary decomposition but with many optimizations +(including not using binary). + +To build this we start with a basic EC signature. If a signature is +constructed so that the 'message' is the hash of the pubkey, the signature +proves that the signer knew the private key, which is the discrete log +of the pubkey with respect to some generator. + +For a 'pubkey' like P = xG + aH, no one knows the discrete log of P +with respect to G because of the addition of H, because no one knows +an x for xG = H----_unless_ a is 0. If a is zero then P = xG and the +discrete log is just x; someone could sign for that pubkey. + +A pedersen commitment can be proven to be a commitment to a zero by +just signing a hash of the commitment with the commitment as the public +key. Using the public key in the signature is required to prevent setting +the signature to arbitrary values and solving for the commitment. The +private key used for the signature is just the blinding factor. + +Going further, let's say I want to prove C is a commitment to 1 without +telling you the blinding factor. All you do is compute + +``` +C' = C - 1H +``` + +and ask me to provide a signature (with respect to G) with pubkey C'. If +I can do that, the C must be a commitment to 1 (or else I've broken the +EC discrete log security). + +To avoid giving away the amount we need yet another cryptographic +construct: a ring signature. A ring signature is a signature scheme +where there are two (or more) pubkeys and the signature proves that the +signer knows the discrete log of at least one of the pubkeys. + +So with that we can construct a scheme where I prove a commitment that +C is either 0 or 1--we call this an "OR proof". + +First, I give you C, and you compute C': + +``` +C' = C - 1H +``` + + +Then I provide a ring signature over {C, C'}. + +If C was a commitment to 1 then I do not know its discrete log, but +C' becomes a commitment to 0 and I do know its discrete log (just the +blinding factor). If C was a commitment to 0 I know its discrete log, +and I don't for C'. If it was a commitment to any other amount, none +of the result will be zero and I won't be able to sign. + +This works for any pair of numbers, just by suitably pre-processing the +amounts that are put into the ring... or even for more than two numbers. + +Say I want to prove to you that C is in the range [0, 32). Now that we +have an OR proof, imagine I send you a collection of commitments and OR +proofs for each of them: + +``` +C1 is 0 or 1 C2 is 0 or 2 C3 is 0 or 4 C4 is 0 or 8 C5 is 0 or 16. +``` + +If I pick the blinding factors for C1..5 correctly then I can arrange +it so that C1 + C2 + C3 + C4 + C5 == C. Effectively I have built up +the number in binary, and a 5-bit number can only be in the range [0,32). + +Numerous optimizations are required to make this more efficient: + +First, I propose a new ring +signature formulation, a Borromean ring signature[*](https://github.com/Blockstream/borromean_paper/raw/master/borromean_draft_0.01_34241bb.pdf), which is especially +efficient: it requires only 32 bytes per pubkey, plus 32 bytes which +can be shared by many separate rings. This is has twice the asymptotic +efficiency of previously proposed constructions for this application. + +Instead of expressing the amount directly, CT amounts are expressed +using a decimal floating point where the digits are multiplied by a +base 10 exponent. This means that you can prove large amounts with +small proofs, so long as they have few significant digits in base 10: +e.g., 11.2345 and .0112345 can have the same size proof, even though +one number is a thousand times larger. + +There is also a non-private "minimum amount" sent, which allows a smaller +proof to cover a larger range if the user doesn't mind leaking some +information about the minimum amount (which might already be public for +external reasons); this also allows the least significant digits to be +non-zero when an exponent is used. Minimum amounts are supported by first +subtracting the minimum, then proving that the result is non-negative. + +The mantissa of the floating point is encoded using rings of size 4 (base +4) rather than binary, because this minimizes the number of commitments +sent while not using any more signature data than base 2. + +The final mantissa digit commitment can be skipped, backwards constructing +it from the value being proven and the other digits, etc. + +Finally, by careful use of derandomized signing in the prover, it's +possible for the receiver of the coins--who shares a secret with the +sender, due to ECDH key agreement with the receivers pubkey--to 'rewind' +the proof and use it to extract a message sent by the sender which is 80% +of the size of the proof. We use this to signal the value and blinding +factor to the receiver, but it could also be used to carry things like +reference numbers or refund addresses. + +The result is that a proof for a 32-bit value is 2564 bytes, and +simultaneously may convey 2048 bytes of message. A 32-bit proof can +cover a range of 42.94967296 BTC with 1e-8 precision, or 429.4967296 +BTC with 1e-7 precision, and so on. My implementation is able to verify +over 1300 32-bit range proofs per second on an i7-4770R, and there are +many performance optimizations still possible. + +--- + +The implementation supports proofs of any mantissa size or exponent, with +the parameters controlled by the sender. Performance and size are linear +in the number of mantissa bits, and odd numbers of bits are supported +(by switching to radix-2 for the last digit). + +In Elements, the range proofs are only required in cases where there are +multiple confidential value outputs (including fees). Transactions that +merge multiple confidential amounts into a single output do not need range +proofs since the fact that all the inputs were in range is sufficient. + +By sharing the scanning key used to establish the shared secret used by +the rewindable range proofs, this approach is completely compatible with +watching wallets; users can share these keys with auditors to enable +them to view their transaction amounts. + +Future work may use the fact that proofs can support a minimum value to +also allow skipping the range proofs when there is a single confidential +output even when fees are being paid, or allow nodes to skip or delay +verifying most range proofs by using fraud proofs. + +The system presented here depends on no new fundamental cryptographic +assumptions, only the hardness of the discrete log problem in the +secp256k1 group and a random oracle assumption, just like the normal +signatures in Bitcoin. + +While the size of the range proofs are non-trivial, they are still an +order of magnitude smaller and faster to verify than some alternatives +(like Zerocoin), and most of their space can be reclaimed to communicate +additional data between users, a feature which is often requested but +hard to justify in a public broadcast network. Similar to signatures, +the range proofs can be placed on separate tree branches in blocks to +allow clients that don't care about (e.g. historical ones) to skip +receiving them. + +Most importantly, this scheme is compatible with pruning and does not make +the verification state for Bitcoin grow forever. It is also compatible +with CoinJoin and CoinSwap, allowing for transaction graph privacy as +well while simultaneously fixing the most severe limitation of these +approaches to privacy (that transaction amounts compromise their privacy). + +Unlike some other proposals, this system is not just speculation or pure +cryptography without integration with the Bitcoin system. + +Confidential Transactions is enabled in Elements and used by default by +all ordinary transactions. \ No newline at end of file From 2404c9df37eb8b1eb652084e8f851b22541b63e8 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Fri, 10 Mar 2017 14:11:00 -0800 Subject: [PATCH 03/31] Replace `bc` with `ec` --- source/sidechains/creating-your-own.md | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/source/sidechains/creating-your-own.md b/source/sidechains/creating-your-own.md index 4f12ffb..601f509 100644 --- a/source/sidechains/creating-your-own.md +++ b/source/sidechains/creating-your-own.md @@ -24,32 +24,32 @@ easily create test chains and networks. 1. Start Elements: > `elementsd -regtest -daemon` 2. Create an alias for the RPC client: - > `alias bc="elements-cli -regtest"` + > `alias ec="elements-cli -regtest"`
- In Elements, blocks have to be signed by a quorum of the federation. However, just like in Bitcoin the conditions in regtest modes are not enforced, so you can simply create a block with `bc generate 1`. + In Elements, blocks have to be signed by a quorum of the federation. However, just like in Bitcoin the conditions in regtest modes are not enforced, so you can simply create a block with `ec generate 1`.
3. Create a chain where we predetermine who is allowed to sign blocks. We start with creating a fresh keypair. - > ADDR=`bc getnewaddress` - > PUBKEY=`bc validateaddress $ADDR | jq -r '.pubkey'` - > PRIVKEY=`bc dumpprivkey $ADDR` + > ADDR=`ec getnewaddress` + > PUBKEY=`ec validateaddress $ADDR | jq -r '.pubkey'` + > PRIVKEY=`ec dumpprivkey $ADDR` 4. Create a 1-of-1 multisig script to use as a block requirement. - > SIGNBLOCKSCRIPT=`bc createmultisig 1 \[\"$PUBKEY\"\] | jq -r '.redeemScript'` + > SIGNBLOCKSCRIPT=`ec createmultisig 1 \[\"$PUBKEY\"\] | jq -r '.redeemScript'` 5. Stop the daemon and create a new chain using the blocksigner script - > bc stop + > ec stop > rm -rf ~/.bitcoin/elementsregtest > elementsd -regtest -daemon -signblockscript=$SIGNBLOCKSCRIPT - > bc importprivkey $PRIVKEY - > NEW_BLOCK=`bc getnewblockhex` - > BLOCKSIG=`bc signblock $NEW_BLOCK` + > ec importprivkey $PRIVKEY + > NEW_BLOCK=`ec getnewblockhex` + > BLOCKSIG=`ec signblock $NEW_BLOCK`
If there were multiple blocksigners, you'd need to distribute `NEW_BLOCK`, collect signatures, then call `combineblocksigs`. We'll leave this as an excercise to the reader.
- > SIGNED_BLOCK=`bc combineblocksigs $NEW_BLOCK \[\"$BLOCKSIG\"\] | jq -r '.hex'` + > SIGNED_BLOCK=`ec combineblocksigs $NEW_BLOCK \[\"$BLOCKSIG\"\] | jq -r '.hex'` * ensure that the output of combineblocksigs has "complete" true - > `bc getblockcount` + > `ec getblockcount` * check the current block count - > `bc submitblock $SIGNED_BLOCK` - > `bc getblockcount` + > `ec submitblock $SIGNED_BLOCK` + > `ec getblockcount` * check that the chain advanced by one block Block generation can be easily automated in a shell script. @@ -57,7 +57,7 @@ Block generation can be easily automated in a shell script. #### Congratulations! Your chain is online and already accessible, just let other nodes connect to you: ``` -bc addnode +ec addnode ``` ### Moving Bitcoin into your Sidechain From d705771708a9e963e5be726966c70780cd67885a Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Fri, 24 Mar 2017 13:42:35 -0700 Subject: [PATCH 04/31] Begin work on new Assets page --- source/elements/asset-issuance/index.md | 18 ++++++++++------- .../elements/asset-issuance/investigation.md | 20 +++++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 source/elements/asset-issuance/investigation.md diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index 5c5a67b..4c1086d 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -1,19 +1,23 @@ --- -title: Basic Asset Issuance -description: Create new assets on a sidechain by using Bitcoin as a bond. +title: Asset Issuance +description: Create new assets on a sidechain, with optional confidentiality. image: /img/asset-issuance.svg -branch: alpha-0.10-multi-asset +branch: issuance-final source: https://github.com/ElementsProject/elementsproject.github.io/blob/master/source/elements/asset-issuance/index.md edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/source/elements/asset-issuance/index.md --- -*Principal Investigator: Jorge Timón* - * [alpha-0.10-multi-asset](https://github.com/ElementsProject/elements/tree/alpha-0.10-multi-asset) - branch of ongoing assets dev +
+

Looking for the original investigation?

+

Read Jorge Timon's original investigation to learn about the origins of this Element.

+
-Users can issue their own assets which represent fungible ownership of the underlying asset type representing by the newly created units, which could theoretically represent any asset including vouchers, coupons, currencies, deposits, bonds, shares, etc (subject to the respective jurisdiction’s regulatory requirements. +Users can issue their own assets which represent fungible ownership of the underlying asset type representing by the newly created units, which could theoretically represent any asset including vouchers, coupons, currencies, deposits, bonds, shares, etc. (subject to the respective jurisdiction’s regulatory requirements). -This opens the door for building trustless exchanges, options, and other advanced smart contracts involving those arbitrary assets and the “hostcoin” (a native asset whose ID is equal to the hash of the genesis block or chain ID; in Alpha’s case, it is the federated-peg coin which is backed by testnet coins, see “Deterministic peg” section). +This opens the door for building trustless exchanges, options, and other +advanced smart contracts involving those arbitrary assets and the "hostcoin". +### How it works All outputs are tagged with their asset identifier. Consensus rules are modified so that the total inputs and outputs are checked separately per asset. A new transaction type is added for creating issued assets (asset definition transactions). Like coinbase transactions, asset definition transactions (the new transaction type) have a null input, but unlike coinbases, asset definition transactions have more inputs in addition to that first null input. This difference not only helps us distinguish between the two: it also guarantees a source of entropy for the asset id (which is the sha256d hash of the transaction). Within an asset definition transaction, any number of outputs with 0 as asset ID can be included with any amount and they will be treated as the initial unspent outputs for the newly created asset. diff --git a/source/elements/asset-issuance/investigation.md b/source/elements/asset-issuance/investigation.md new file mode 100644 index 0000000..e14eb32 --- /dev/null +++ b/source/elements/asset-issuance/investigation.md @@ -0,0 +1,20 @@ +*Principal Investigator: Jorge Timón* + * [alpha-0.10-multi-asset](https://github.com/ElementsProject/elements/tree/alpha-0.10-multi-asset) - branch of ongoing assets dev + +Users can issue their own assets which represent fungible ownership of the underlying asset type representing by the newly created units, which could theoretically represent any asset including vouchers, coupons, currencies, deposits, bonds, shares, etc (subject to the respective jurisdiction’s regulatory requirements. + +This opens the door for building trustless exchanges, options, and other advanced smart contracts involving those arbitrary assets and the “hostcoin” (a native asset whose ID is equal to the hash of the genesis block or chain ID; in Alpha’s case, it is the federated-peg coin which is backed by testnet coins, see “Deterministic peg” section). + +All outputs are tagged with their asset identifier. Consensus rules are modified so that the total inputs and outputs are checked separately per asset. +A new transaction type is added for creating issued assets (asset definition transactions). Like coinbase transactions, asset definition transactions (the new transaction type) have a null input, but unlike coinbases, asset definition transactions have more inputs in addition to that first null input. This difference not only helps us distinguish between the two: it also guarantees a source of entropy for the asset id (which is the sha256d hash of the transaction). Within an asset definition transaction, any number of outputs with 0 as asset ID can be included with any amount and they will be treated as the initial unspent outputs for the newly created asset. + +This technology is similar to colored coins in many ways, but explicit and consensus-enforced tagging has many advantages: + +* Supports SPV wallets much more efficiently. +* Allows more complex consensus-enforced contracts. +* Benefits from other consensus-enforced extensions (ie confidential transactions would not be compatible with colored coins on top of Alpha). +* Opens the door for further consensus-enforced extensions that rely on the chain being able to operate with multiple assets. + +Currently only the hostcoin can be used to pay fees, but it should be possible to pay fees of different asset types simultaneously. +In this first version all units of a given type must be issued within the asset definition transaction. In future versions it will be possible to define assets with a dynamic supply that can be increased after the definition, allowing the issuer to create new units. +Future versions can also implement consensus enforced interest that would be interesting for p2p lending and issuance of assets with built-in demurrage (negative interest) among other things. \ No newline at end of file From 0f79258ee9fcacfbcda138acf4a711280aa8335d Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Fri, 24 Mar 2017 14:06:23 -0700 Subject: [PATCH 05/31] Move Asset Issuance into "active" --- source/elements/index.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/elements/index.md b/source/elements/index.md index 9ccec73..0860184 100644 --- a/source/elements/index.md +++ b/source/elements/index.md @@ -20,6 +20,17 @@ Elements is an open source collaborative project where we work on a collection o These are the features under currently under investigation as part of [the Alpha developer sidechain](/sidechains/alpha).
+ +
+ +
+
+
+
Ai
+
Asset Issuance
+
+
+
@@ -157,17 +168,6 @@ These are the features under currently under investigation as part of [the Alpha These are some of the features currently under development, but are not yet ready for deployment on a public sidechain.
- -
- -
-
-
-
Ai
-
Asset Issuance
-
-
-
-Users can issue their own assets which represent fungible ownership of the underlying asset type representing by the newly created units, which could theoretically represent any asset including vouchers, coupons, currencies, deposits, bonds, shares, etc. (subject to the respective jurisdiction’s regulatory requirements). +Users can issue their own confidential assets which represent fungible ownership +of the underlying asset type representing by the newly created units, which +could theoretically represent any asset including vouchers, coupons, currencies, +deposits, bonds, shares, etc. (subject to the respective jurisdiction’s +regulatory requirements). + +These assets can optionally be "blinded", causing the data in the transactions +(including amount and asset type) to be cryptographically obfuscated in such a +way that only the participating parties can see. Particpants may choose to +reveal a "blinding key", which grants visibility into the transaction. This opens the door for building trustless exchanges, options, and other -advanced smart contracts involving those arbitrary assets and the "hostcoin". +advanced smart contracts involving those arbitrary assets and a "hostcoin". + +### Issuing Assets ### How it works All outputs are tagged with their asset identifier. Consensus rules are modified so that the total inputs and outputs are checked separately per asset. From 98e03f65f94e77e98e28dfc964e013bfd81a6db7 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 28 Mar 2017 14:41:06 -0700 Subject: [PATCH 07/31] Remove extraneous white fill from SVGs --- source/img/deterministic-pegs.svg | 10 +++++----- source/img/time-lock.svg | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/img/deterministic-pegs.svg b/source/img/deterministic-pegs.svg index 859969c..59a28c4 100644 --- a/source/img/deterministic-pegs.svg +++ b/source/img/deterministic-pegs.svg @@ -15,21 +15,21 @@ s10.8,2.7,10.8,6.1c0,1.2-0.9,2.2-1.8,3.3C61.7,41.7,61.3,46.8,61.3,51.7L61.3,51.7z"/> - + - + - - + - diff --git a/source/img/time-lock.svg b/source/img/time-lock.svg index d05fdf9..2715a13 100644 --- a/source/img/time-lock.svg +++ b/source/img/time-lock.svg @@ -5,7 +5,7 @@ - + From 775b36724fc8ae4742ef5d832c68b3a0c18fe02d Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 29 Mar 2017 02:56:37 -0700 Subject: [PATCH 08/31] General style improvements --- package.json | 4 ++-- source/elements/index.md | 2 +- source/img/liquid-logo.png | Bin 0 -> 37449 bytes themes/elements/layout/index.jade | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 source/img/liquid-logo.png diff --git a/package.json b/package.json index 0737afe..ada1887 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "start": "hexo server" }, "hexo": { - "version": "3.2.0" + "version": "3.2.2" }, "dependencies": { "hexo": "^3.1.0", @@ -31,4 +31,4 @@ "type": "git", "url": "git+https://github.com/ElementsProject/elementsproject.org.git" } -} +} \ No newline at end of file diff --git a/source/elements/index.md b/source/elements/index.md index 9ccec73..0318659 100644 --- a/source/elements/index.md +++ b/source/elements/index.md @@ -19,7 +19,7 @@ Elements is an open source collaborative project where we work on a collection o ## Current Elements These are the features under currently under investigation as part of [the Alpha developer sidechain](/sidechains/alpha). -
+
diff --git a/source/img/liquid-logo.png b/source/img/liquid-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3330b9cd82dac4757ae4eed71bc704d5b258e4c6 GIT binary patch literal 37449 zcmeFZg;QMLvM7wZySwYa;O_1gB*@?z+}+(>gS)%CyITSz5G+{m;E&{-d++Z%b>Bbm z)tjoR*}GTwYFTY-?OhY8q9l!sK!5-S28JvvBcTQc20r-y<%ffLhbV;xro8`vJF7{H zfz{3u9lzheJILrbgMlGp{`rD~W#!<3fkDw&X=uA>D=P4r*xRvyOzn-$SUl_;-m$^J z1U&fOFYU}+Kx7_vwx68&JOnBJV(`6R{{gd7ko`q*u@R)uR#YJqw|6ol<7DAr0Z<4b zkdcuIIGLLBsYyuvoBaJwkiyc%#et8N)!p5l#U03E?_|Ns#>>mg3SehtXJ>xLV0QNW ze^AH!?F1tN#nxpOOD7nW@QtYvthTWcybqQxjG*TQfVePcF{ybZq}C zyLa3EH{t(BNDq+1znJ|s;=gng_#-)=nwhh`t?M5XXnwMC5n>nktI&Uf|HmT#q7t{a zb8s?qc77)l;`}$sKVkogul+x4gt-5U$3KDpNucax^{y%Ck6c1*|7P${*ni^d{BI2Y z3H%4aAJg-xSb3P)YD-wX8}zRh9Gn0F*8g?nKPkoSZS9@Z9Y7{#ep#E(tp6*vz`HN-DcYM_ znR`lrT+D>n0c>1+YyduXb~1MMKNkRA0oMP(`G*95M#P=WKrZ%98us?KLVwk;`*TYM zWZ`6aSNuOQ{!J{v`X`e95n2BV+rQBFxD`Tpr~I!RAcT-FvLy=!CITiaA*$g4eyR_j zgFTXYani#L{5oC$$3FCZ#22290WJ#99-4cChAo_p#sFmrpzw6Sjs*~prxA&U9 zw<{l#hU3tUpzy$@0{-96|1-h=f4v}oi=3>ji@-6|2ff|;tdRYsd{Hm`r*fh~MOm>G zb`l5)px88+QnF+^A+W+xqARJI&fs;b9Bnb}ImWGu(hmoKh!G)_48R8w+VLbBD;x0E zHG5NhOq4ki$I`^Nriy7YljN08E9or-xk(e~V=FQyej^XO4n)`e&`B$-qe-p47N3=L z*~PBj`&PG9%TJNS8V>pscKOWY{W0~-EosU+ta^?4@kCluL5Z=crpE$+)&(O=-+^a7 zMsh`nYsey?ZCLmd*50)Yt|K)yMq13{5&N0x*(q+_^9?Be+jG>P_zmO=4_G~rn}${* z2e>{sZ;6+(AyG_E_3zS%cJq#M#BN*54x4**egX;&CEPq(G8iNfChxAU$Xm-!++8yo{1wcXtRFbYwHo(<>9f1F7=q$pjC~pvJ+5q+AJ@!!1ZQSs$UIY>s^;i4 znrBW5mC53w)tbGP1_4pzUqL7&0xUu#*XcSWv-s={4rT1^qNo_xPLe!%%>y8*Gz)I| zlU(GaIMN79e$8dzGkkZTrPM-&VPd0X5*W;(pzMch#(UXSm&|GD zIl5=$7pv}Mm1Ygn3$32ioJr!Mo&3v)@z1KI2Dmro-fqhGxC-9!0(IT13PZyZel37O za+omJpC4k0{fP1nMVlZ91F>Mj&w~CYSxZJZ0Htk7TGs8NynadJ(V+|Fqar5}fvL!4 zD4tORA14vb!YQM!??m>9t`rOIyCDD&v7!NO${a8)G{g99ciaW)arduSt6&#F`)Q!{ z`*1td^@|U~ajg~^4ZqJrSmr)*?dfv0X${+rNWLo=_zmt?41mWxHqP;Q@nLCyZ}Z+% zvqPIk)r4&ZY@(RJFRg=fd43Ts)vgDRvbK+&aC9wgradszs7UWKCHuS6H&DF00gh$n zRGNUG2n+oSO0$SCtBv(=L`xD}N(M34Xfm>@v5P6ERHH%-NUM^tnS752sg5|AnmR7O zo{hoRG~>V-o|nyjq?wmi7mQ&x=&yU=NWX`Yv)HGstLYE8+c8Xj+f4ol6J+}p-`;AnMV z{SHSmc{Mw%QIM4jOiNG4!%vpOcBjHt^jFqvwS>I*Lr+twB-vSW@4sIR-Z5=9a z=y?aB9r6%LfDpTC1@r+J`EBXYi=d-%r@>@{F!upB6FVpF!OVz{U_!fIfMYCz{7lDYQEh@%?2kYWuAe%|vV!$ZpxGQ#piTm~L4%jGZ>-|w{CYf=9c8zjs2IbQ0*5~uB+w=I@S-*B<-BwKv)j+-8=w+S;6hPD%UAx}Uv9byP6oj5xT$Yuxa zl5Sb=RJ|zaqL(4l`3gY%Y@|mYY6p|OOJ+)o!cl-9k6{8zTWsFi>Y)ya2%MP}K zhXw^T<3wa)Dkl5Y&=rs}^&UmND3zv?`pmbmsJ+>%U_GP}z<(}WlO~+ukr|eai8uF! zw=|_dZMXE|tDTA`>3h2??t>}v%Ex8a9 zG99kPsYS8))7RM%z1JI0f?tdKbFrfeKcQ{!gnH;V3({~(3%`|z4bPQ$lwC08@&a3+ zzn$yr%?%w~8X9Q<$Z~(A z>Co=zMn}3#E??S+JK~VRx8kZ614-A7ovN_E*?oE#9}(Sk)_%|GN9*sM+qBi&RNAvE z*sQ(>e&M8Z_Ar!HtP;CTL)h)vd%Am?o3=gQXgJ2vNhKW!`~69j`^VC0dg$lih_@EbwU-<|>_@LBSW=0}=FTZl!4qLrr6QzyGk&3w zRKcPez1D}PweTrv{rDI1;*5VE3@E?XGMeud)zunW1{_!J)>K!#J@g6*DaJ0uqs6iQ z`d$;RCqy?Fo4p`9l#>@?i2`*Da1JrqZaE-vHK|`f=C{4EIMUxkbzzG9-;2K()HNN> zsKY7?9a`sTJEAt*(dt6NdY^wixA+XlTi=YS1la~AKr zY$u*)OtsB`O8+80So#r>h66hyxhGauL#G*UB?@=DFAjk?L3WD{9u5#==#hMz8@Y1`F+H)L+}US&oZc`OmJ)=LFaN7It)%Z!JlULsas3sVW{L!sqb5 z97v9yl@NE3#E7s__Q#;rI3F(_mNKG0c%J@Zw25I5=B$U%^sD~TQ<3#}IV4aO8DQ!-2wm3*BH8Hv8PqkPBgs1D2)iH+VCyXydz@n;e&6QOu! zJc13~nL}Itl1t=p)KOZlHK7Tghepyr#Yi8DPk^%9X`_2-Pwq%FVh2XAX+Wx(`V74} zBR^#Z>Y~Q$iKg7`6{RVKy&G39(>$>LwGsBMS5M9N2ddAb7?ADB@uN*|jOJ1tM z*=DW1h(wbXS3@7uUq?G;V?SvB_DNTi^DKDZ)7NT|a~Hc@%0E$cGB|qfh+D*cP3-I3 z=p8zkLA>Xe%&kjJ`M9<2Dykh=V3M$!!M5Mor|+gHhvn|RGFm52e}F!&GejZBhJ)V5 zL2ZIat@v~&4jE=Q#lkGi3-|SY;c;7v<3?OE)jkxbM(ha=J3@jj0FZzDw6qvCbYIV` z2Fu+0USR@AA?)(dlQeN;SN)K}fZ*QaGNsyepNGjskwD?QH|5rJHj7amV;mT^LH8&NdI)M2d>WVw71Vi&?bfIGbCn~z{~ zm%VM~OGpv2b<3{45foGWMrq#P{gH@Tm}v2Y-vt1p{1z#aZ60!e_SK`nlwnR>wuJv| zj1n7n^CK|>eS!KMH$j%;{?NLZ4@SG<{`@a8=g}6R&dR-Qrhs&9|1F-tV(PSHG)={yI(gN z+4n7F&GV^v)Ahe*}jNwhT7m) zJwD5?jcv1x(>AO!?t3FlSN?Lrpw?ptv0Bz^2TEZ#DRQnDck$ zak2avwn0AiSESW@7;ifj+7k+%&-PmdGP|fsb{0K1;kBjY{-lKy{aKAz(1ojXC}}Tk zA4=yQ=4G4Co!3Cw5Z?Q=OxklhF);n8hTLpZ! zZ0z$!njPvPkyzh;x4n$6@uAUDn6+6^f0rVzNogj3OzzWn+LKrEa$m9S09&;rL2FR7 z&U}fI`fNmVlt1?2Z*GW!{WIl|S!A|@*AN6d4C(JW#2jS@V|)$PlXB zFX6#9hJ+gE{u`oh2UnruWGp=!HaN#2Gd;R`)JS`g)VTU>qn_@{x1~CjrG6t9Jk;_; z1o8f8Q6WOt4i`=8Syf7WKJQzRKORDd0<{T6S%!U2Vxtrw2ju%Vqf!AB&ee6-(!yhpA@+5_q_PXJOvDM6w{j4 zBRO*a6uUR~FQelH?uzFt0tP!PYbg5zN@)d{21Gu}>S3-D#a}#jL0*^C2?4QSWQ2n` z#mD4N<)TWopNC*#CP$KMc@88hlYe+S1ifq+G^rujSVjDdoP>pq@mYzS`tP|V-scum zUla~TKA~P8`W8sh$}>J`?HjH^KUx_08eR%)BSCc~JCgxXmbD#mcJ(#njWFlABkm&~3#!+)WJjcrg z;*+uQJufA?1D6Z}`=v)sspb8L$y6Lz>V;}!hSYhov(pl4>r_gdts3ed{0}1fWz_%5 zkRpzh@AK9VtCZRlsC1+^BGw#=k{`r7!=eiP?5|;XEK8Ar$|?l62wuexKKN{qB zTa(Pc-Am;8G4&Vwl+><Wdl)PJX{c62%~y&@j#dm5b~&#uU4pjhKp zW_dITH_~1_%5t*fbdmU zpe){83bN0+6)lTlG-)8Yc$h?|`-LBioEHv^I`w6H#~ff;F`KJqTmQM_5Q7UAVkjK- zf)F8eR19qyc9AY;wbTbMR%-3jcK3sW^N%sBRv`$<8Mup$rduTXtc-KlAOSmdndOx_ z57S>6s6;&cV?#@(ngjYGlq*Ncdx>LKvHtUd$0~X zOMU#i8niQUZn=D}*0L0dJdjVk-k{R}bfj32X;ZVy{U$bJB{N~oNYF$GJZA0K)usMC zSYE(!x26_HNpa<9ujAgRAb$LqKUADYqxR&~zNG;ajZ)4!Cqe8E^8U?Sf$|M4IclUQ zU_6b3`DP%4&4gsL9yFBv>qbq>a$5|C>~^6@+I_5z7ap=Ny11~D2>A2bn0XD00oJZ(r#)i z^B+t%x}i7n%>1)8z#gT{*rl!p63Bx|!68+lz@~NAlvwj8y70BWUi%nR{YT9fTs9G3te6X?N|Y7OYuLV;>%%!^ogdbSw+tHi(P`+q#;Q8K zBKPx;8qH|A7x!vr@lng)TT3hSOVUERysg~1z)*|GDGA~SQa0;y+*7C0ZOp~q_-Y6{ z`A)FCQmh1c+<*NpB)_TMXa0qVLA|oP{7mZm@ppvMKm_~5v!$D441ja$(P1)$UJ|4a zOQD?cGuc02mwvd|Zqy-a#zp#e^@l??Sb`-Y6hcnh*yh8p4^B8sCc*KfgK1sn~2 zzh(C8LByYstqx~%KSM)tFEIg}wanU}LFR7}-@idB(3A4ot>}J8aR-YCVqKWBbn|?B zeZjf4sbP2SorwlB7Yk>A00_cF7SmySX08Eigum*k~vRx040xfZ-f zSxiHa^=oNV{=8g)2EWyg(bT2(;UKk)x_}V5Me4=3rIw{-*28`!%*hAuGr&io^LSxB zEcr5N89&rB$v)kn*fop|tOj_|v*~bQB$$DrD zMBLXkEi^!bxL9-b@@I1R3LNB}tnWws(8+HMsT*_T3P@kV+#W)0>Mo*_(4`d3pisWm zIOJ{w@-6UBa~L=fnBR4Kf;Ko<#uB^Z(&ty$6PRTYaSSi(=(7v8J#uPNQ*LfBr~@SA z8cUxa55>bv6+7Yg*Y6-hhrU;_RT0Sj{^4hGlXD!78beTQiANsg3|3_LT`A}nYwHWn z9)SlrSm-4|0+yjPXr46gr`I#*PQN4?*i|LHiV>l;f6zH};|a^>WsYS00)7SNHyGnd zc@A5Dhbeq@U%=q+yo~D7;lgmQuyCW_LbEnFnb{-}yjHn`X{|ZB7TqRmlWOz#yz^u; z$a!8g4Ym{{Ur6{JcQ;ZjU^@pAkrAmV0N6I39BH@@oZOSC;P# z;vVtv4)_2s4+h_V>wl33djX+0hxo!uPY7KS+E(u@;8@4n$>ToWI(Lz*w$*pZrw7v? z>*|#ol22*700-roFgAS-pmCU8E9iBy5~=rVXklW1ufrEIj3U{(Mwlu}=cKcIm@LyO^vUdqeq2i0xsGmJ@9So7%)mX}TO9ma1I_+W~tx)Tt~_ z4U^VRhemG-2dq{qH8s-YQsy1@Lb(QjHfZOoD^(xLsG)xut-YePA7t626$wA1VwuZe zZTBaV-ogW>pc8_=?vRNrc+sst(VYr~3`C>QZaK}<^GSKQ+@GGKDWcqGZ7dwP$E>FF zrh+k-j^tPw7k$=X+Vl#1Wt}l(v(vRkhT9vgT5$+zR=(z&gd7viO+ngM_JnM9p3`Pp z#f+)tW)p&l&vCWcGJBI}AAYg#dvQ~>V;%@QdJ~uJi{d)oT`#^vRd=y%*aVOUzw;#NHiwiubsLL*LOF3tJC$xMX!MaN*oQ8 z()IZzSJ&0yMf!GxG*VK(JkMs??OMzuvAx8aXf?KJfy8%f^^i$Q;{)lMnP;qeX=c^I ztw^wPNXF9TRbSzL!Kqrj-)j`+?}N&H>h{n3EiZ$cBBZgkIsBH(IPVFnbMO(yO5d%3 zuZyjpgCxz|PSwxI$f++dH9-9Xk`;)CYLF#*t@e@K;!4Tk95GLVU6#~(^BqBKm zM=ef(%fP6*>-sRGmZYz&9lNp8q4niwb0iUR>~QC91w|1lEedg7wCgCds;4tUu8?)z z_eN06d{6aaK%nv5upuDiXF?I}ujr)#F!{!YSyX6IDC4W%V9y49HsIG__Jvcx6bL5! zb{dr!HjvY1RmGoqQ;2aBqot)~3&iu>e0ss*Z#(UF%+H*~tn?ti(cLRaOAy-l67p=i z0uwY{2})=}@xE6>?9#5wDwZ1LctMkzGO$R&smsvH%#vaVV^fb!5n;*_CdMckExMIX zQD~@kh&!YChX30VLSu9thYSGw=ivkdnTjsKPgF5{bXkNSac~ALGV6B)rR8|!nVgV` z#CBd0JdtoFV9AR(Ed)|&G|=-A(r;vT3+>>pk^aR5IP7SEWvi6-Y{~|@&gm0W&6o-| z#HH;Qw!vxb0CyOq2Ykw5X1Hy~dzzN}-u_!g11Pd(0w#7N#W<^Y0;vh<5xwjKRvlHg z!QYuZO5&+cT{Wl}kkM<>Y<>%C{PPO>LUq9NF|V2vUQlk;h=Qw$Fqcg6Vu$@jm_a=w zpWN811S@P;7Glq~dw{$6qRr1?ut~&WV$4uolneJmxb z_REYWAnv9zJw7U&5l0nQM|D4aj?Z^EEESP%VR}6>g*nWcY4H*i=(^!1e-3(?BLb{` z?o(`ROfPe9<{#7&dTG+33mtKUFon(~QR+sb z$MPEVexO@5A~UTWMFMiBf`bdAp2S3{>ZNlF(XSnaU4BZ}b(P)*Bkpgiu0~pQQ^@!* zRb35aY^Iv6z@>5;2ry?AsxRbmrO>RW=q^wf2*9TI&P|h<*NHP%rlYY&Suu@F8ot%Wiwb8eMj%b{ZJ2T*`>ZROAbQT{%~w%4l02oDMnRAGm?v)$f+`MACD$yik`CxdES4d)tbuGu#vWq;VJu{v#W zEcv5p8$+6)o1>7yW(pH7Gi7nG+<-^zp#4FE$=IwEF;ii<#lv_aWm|zUbQ_zT^sZ%= z8}(u@KAu59bv^0Qz?4wm!a02}6jMk$B$_)IATOkGCq~q?*=DWwBA%Gv4}aL0HOQmR zI&NmiC5eC1gZQe<3k`S?^aPiNO?9f*h3nVXaH6vQW-_YKj(3~&@_aq_nG{9(v42vY z_GfT?{KM;NjozHS^(P~y9@Y4hfPLD#3t@-aQdvQV`X~e+daFvzl^UZ@%jK#j0UN|J zXl~xApYV)yt-kCeIq%ey=EvmDpC5krB54)$@tw|aR8C0=@rQ|)rB}sCqwLIod4i&2 z0uF*1aoVUX;?*R_I8iiyio3g?=zPt)_WOB7D-SrT_+@OQq?dN6>KNlw6e~*8Kzps6O_QNZHEj%0L1dUCO;&{8Y!55~C&`8G{z?M5IE4|O zd*Snri0|Y23v+sd%@d*yPu7Tt#%&#$f%`6Z(qb!{%dtH~rn(Qor9})lTT!ZXzM_;! z${jM`>%Az|=itC2;UIFH!Qa6GR*S`~;B{Rh{XmZJNLB4=2#nxCMyXgLUcdHId{hvf z7w@Kg$(@t=gb`W4s_>@99&E-&p~0eWIV{%#W<5?j6d*^l4XdX9h2V|U(^Z_9A(50g zemU~)R|f;^!NjPQJ0a{b2jFLT;lfd>%stLD3iDQ^cFgdJnoiyka(6;pq|ii6Jve*K z4|Kxy6D%FJE(^bn4oUK`GDfM&g=UpHAt#Pi#_>o@mrW?H#S3jt3ngo)62dDm&O%ow z{*d$xT7_QCs!JXn+2ip~GUoed@$6^G6L^<_gumzA%XV5{w|;#edI}Q*5vf&9LxAi= z0#2{8Ve6%?9Sh{5Ge@ue<04={1Ev+fJx{r}5#eDAP&xpmIh^et~ZTeCSJp18iGB9zA zt9#IP7ngg|hQTiW$frsr0?DrO*wZY*i6`v) zfDGFk;%#O|-J4k$c1KxhDf=FOHiVBsSjwI{0H#4rGxjy&!ux>cdpL*XR)@~W28FBD z8DQ2}!X{mOQL_hkxX@)*f4k9WIf&U$D%V=3;)O-mx0)3%+a|{cUME*NX?w!UBFkdX z7}ns)+c4FJY3V zsFAy9Zm5b15Zjk&wcpF@5BLNDGZg`^*5`KeMJau*+k9L7e6~qF>8r)qPKTO-Y#20p zVUQD@JSwS>PtUc%P1LP=O?CAWEBYIb+?@Fj6il~Ttv%8pnOY-Y*+S8nVN}5~sftoG z`~hR#*4wm{jzp%QcdMKNTCzgczE?|ZTzB>~+ybsq>r4o;o>}3Cx2X@x!opp-`+-Mo z*G3fQ3e%VMX{>UaGcRavY?L>U9VOd@j!pa-x;nwELONhmBCS+s$}+l9_@JJj8bsBE zZqdnYryM_lC12wYndWp#ZgWq*h%R3_A9v%ou+Hf;nM;bW8a2}U_lyf4ZmH7cV$H0= z0|uTPiIz1e2+rf~gtAD*hf{ukmTGxrWHhj{vCQ-;HO^0dPM9!|0*z2Oc+$8>`=N ze!G_5Y<+BGw)wj4{cy3~uy<`FXL$7!_3qoO0GRl7g`JjxRcDX5Z)rZu9QYWp`^q_* zb=Q86>N80^ZJrpv{ts|HDJLAzmw1yB1omH3GVL>4)+1`hn(9iLEeTOQUJubB=qR=^ zB#V?~#mkqjD@?e=_dJottC82`D=8kS&zBX*F58Dag&#!QCX@OOeRseG-cQcvAxWJK zv%$>gz?`c-=MbNtZ*{rLJ?9XXQh#P6pbbsZdx=2%DLtJ7SH*vOOV2aIk>A0KD{-fk z?f6?_+|$lPdb1EGQLd*2o)~+|c$MCNfpD1-d_W2kS-kEy+I}ufsXOazOH&Xzatfn9 zOj$L@lSsRu&1$z!!rdrX`l|iZ%O+yRaG?6P0i4Kj)$NNzksMeAYe;9-W)PtufWndP z>X8zIZ{*XEz=nqhFP;T#L7+@4s-Ws4oU-p$mMa%h;)%&^2{9Juy`r=?3xQNbBtffE zd;DrmyrR~f@OGd7i*k+@`;4Cio&>Smo`~uwPc8n!^0@1rR*o%eW|=4b*LC7*lPWwD zDKM$>n^JokMG+>k#7o;YiKK`R+?tW1&H68cAPf)2I30usbS*hpv$;jNJ9++lK{nBd zFXvbjQ<3r>3-P-F5rOrDnqlN0f{(vVOH}y}A=O6eB*nClVj^H5aKHjv6mnCp4C&!- zzSEf_k{+NY?%+PWAZ`*(1K!-NFipCI^L;wh(w-w9e{VL4UN;#u2PD;l5>Mt?A)|LR zIiKl`B7D6bPWG`9>&xx}Lh@HH5uFs-zwS`h0iUlX71Dpgd`$*=p1{#*TO^?tFj3(R z`Kec+PKMbjXmy!Om0Tq?@hPrG3!u6QIces7AfByy-<#|DMc@J(vsO9c3n7c8SR2Vd z6O@n4cjUi$@-U>9&W-WAx3YY&uPjsgyf#3(S;;r9@h#C}`)0G8_Se9rJjQU*gM-s^ zPAPd|?HZQ2W`nsC0$#tFUkGPWb*uquP#R6MScyIKIO5heLF#8PaJ_&pWdrrApgCQG znw1LmvNR)9d}KUUiFQH}CfZ%yELFFivH7*7(^9u^JpQFdoIOW1Nkbi!4(V}EaS2$H{-PGM9(5>?5Dw*eh1Zj2ggmW$ zLk^sWhIm%-nDNDmyt$~*O&D)8{^tR%%OX{mEV$B(T-F5&6}X~Py09#e?;#T!<+SMw zF=r?v~E(7FBi;x7&P1u_7XggFBmcR-ZFdPuM)YN zQ_pDG=b@7688h=j%>_!E9U)vM0@iHOSpyV4BAT*kc#m#!) zCH`QffAisX+ah%LLZE`2uh%q(H3?c)8in}bEu2Bx;s}|Z(m3BH+1Ho9vlY?;`#!qADwKZitHx@ zdabX1RL74gjQ54;v=J99V%UV7OB5~9SOyF8ZHf!m;4KZ{rtFi4L@T1%mBRAWWJ2iM zg;{QqArVM72x)jNRH8_v#>FD+V_ba|+i*>Y0}0aoT8%`fq(KsU@ekzyn9M3}+~QZQ zEXFsCd?!Gs$)LslVVZ)m^vl@|?}0Mn_pTo(_a5yqH|~if^X#mhxp>0dDH)FfwxOzl`#-5>)SJvLlm~}N7<#1`v`;#3L{rn%F>o?xu}jIA>p%bE0$lQF>Y8h+GIm#U>s6FQ&8cy#<(12 zMnxrfc>?Qbp31k(#tM|<#srrWewK#Z6z)v_d8x{!J8Vgc$t7Zj58HNKb59kxeNUFpo7 zo;BKiaMAI@oa+coWFXn397F8%nlo(tS076e7ntdGMaAWn7slm*I;EWQ+?(-y)wf*y zTFULEFl(PGGO~^{@wpp$AVGxXQKrT$DlViJ9kk%_9fosyqYr; z{rqc36YOFzM2<{uHS%5HT3bJzQQB;4wt2eXoBs`=k-3QIh=P2<73|DaX!#YzFg8x) zX3Uh&<#?j_&YT?GH^^dymGOJ|h_Hbi8B+wRi=oxX!rw}ga$j>mQ5LZ(--1VFJ86jl z7`ku*Q#Th2N+Cb6XFg|X9&{)9F~-v_ED%l@o}a`$$Gm)0d$R?LXkTOkd`TCw4cQ77 zG>ctqo>HngRwgqIhU!e?%$95y3Bhg}Fwiy!2d6}Pj^u^|ps%HyG#sI3={6Nfd%K9{ zK@KmnQCCB+M1;187uYd6eOYA|a;Va2v8GNVbm9xvgTnPsNh}sq3Ak2<^`x+LkVG9u zuf|Ok-HxZ3s%rnC23?Ih0 z@m~7TEqL!xCxGj@(b7DG0n`ZsEDA#33?RpXtj8}T$U z!0A_CZy+=zlWuc4Z9X_9*2zUZgAQ|sOBd?F6FD{`gp&ldv+b5;`&6wbI@mxUvA9ns zj@|flbUiITHoCaHR%n&kbf-!P8?dSWJ_Gb#XLx0J{MpMX?F@Eu-|WN=lA;>pyuRw5R53=>H`Cc@YlK1sPM$JkA^~Qg>`G;j8hB>O zhsU-_wG05sw{8+Xm;90FFX7wdXKfrNV#M}1@FyYQ3*OZU5~%yw8W4qdiTB9Fd>R?( zi=ZwU(vU5?1ld zlu*IMsK)GJfJozm#N?^|g9w+U)XNOETFDl8`lNL;s`VwQ(TmXge4Bi%r(!;nYF5%JBnbtD#G z>hnDo%J)N%kqd`^#OTAK7I`x^XIcO-K2%K6o;xsRQzGF#UqhTp)5@3^M$M+&<~+>a zZr_lyb&Q?`u#OjF!g<03HcA#e=t&K+m-+%Ip_dXE8~eg;p2FPa6vc(zNt+8&-G*+Qg}Db6h2YF8X&Ccw zPs-8@B(&2N*tFLm3VoL6LPpY*#9BkZu9ZkF*7Ss6_)EQggLLZ_NVeu@aU-K7Ro&Q+ z+f}H}j6g2c4F|2Ny;#+N<}JzQzC-z9{f7s)D4Z(h7zppf(8L<5g{=5}j22f9ENfTV zC|6F?3X3#YVGoLWi@7}Z`CM=bpRdF{MWnt)S7SUarTLWl_dbF<0W{+(F~5*ZdZ>0q zD}T&)Uh99OXZ@@j^ef$a4|FKolN>>khx0pKOaQ92w7)r@zMM@C43BfSLXVu>tz~o3 zYy2%0-5hK5YbfUkP1S4gu@R0n!p!Pv?`k;^0-731gZtRBOer@6k6acGOu|30S4t0W zftG7e<6#D;J@kcJgNnCn>xX_u;$n3=F&Z6-6rJn^?HrMdJ)X`&PI^n^qAndNX&d3n zC3Xi)vlL~LDL)D%gk;f8tr9k&->H>SGSzbzVuN7+L|wz$`(yS+BuG7^#eHY_DViJO z(q^w4vZA$v4&#^vywDpI^Z1MQ{VhCyTS7Y6qM!!5w@&IMR6g&)>A^TFL*`KkYh;n?w)rdExMTyT1t4Q#d?K-{7ZEPwz3!@ z;-VVj6n5yV6xj^fCfteCtMA|^^^ZO9t}?2`?Vdf$>+)Mo zzP#QKE*MJ+GYr1L&S3CQbNz5;(+JnTMscK^aeLF&hqat_Jj^|`lSs^bWijU^(>WWw zd>Gt7<(Xr)owmnPSCX$5my+1Jm0KRQfmpnjN`|yAK!GfRbhM&pPzT6d%Kw$ z&QBh;IYusiU+!(8lQz%v^{ID#r~TMhno?CW%>2HuY^^A~hUg*Uv$QsEG~VPOCOu$V zhq;YPdO@i{)$uEHv{?&lH2jrJ2+>cJl`eNB0o@iqeOHExRNO!(1OPYy#Oj#AjtPPz zGBX|!=%vVxnq3qw_yJ^O#@)xn48Qek5%F`VR<(Zofa?<#Ywh!dI-{NDAVZ<5nI!W5 ze13*Pmvy@;+#wSIz+m_x(Ly=weTfIr+{9wGxf|Rt@-6WSiV0UFB)5o& z!=V(zNZwzj4we~rvz#~DwC18cU7bNHF;7#{^_htWix``qj%U0U0>b$IfRk@E%C`04 z1#XRQ7cp6wM_*l)rI?aQOK^}DU_z)?X`F|Nnxjm(2={Nd82NGl69w)~r4X$?oAou~ zC#lbw=2d9lAT?}(1CYPR9;yuULc$kQ(YR$P38lCk^x%&jBWYG35qgTB=+TuWtS`<| zc;p>@UMHk?$F$L`E0K0Qy;*?5@V-?h=az5*=?G4nI$1-c@z}{R?Egn}wStMp9IwX)l~`f!;N}|+GnS$z zIWC<&^WoLqfBhFgg;&eIkEK2|Dc-Qq101N+{3c7tDMA%>+hZ>_cHuytR;#@$kV1Cj zMGL}QX9w z+>>dQX;d}i2E#uX7<1t+Ku;W4GmvLL@G1=4x!03PLF0NHB*}fK;Xtg< zNOGRRg$}8s`P`RHx>zaGH)ZWI#jh`1S=V7P5>-k{3KdQF!lrXA$h0>5MF51SYclMW zfL3gC;Aeqs>So~oa_f2yTC@iY@e97Byv@$0D`kOwNkJxu$rdho?rpWqykq0Ct@B}< zr-hJRyee7PevW#7)AVP!C5Eim zW+&Q;*cIh#q}642E#E}FZNiLtNQ;4aPm83%{Tzaa6Ong8<5nnnhsqu&@e6bL<<~&_ zoNkk1+85)nPmVGbu;1M}d**J#p}@E_j$_1GzvkfAVR!Ly$Bqh^3phQzB;`ycZq zpYp@j2^bSM`+K*W9XyFaGtEjAG)*uNtV7$wT>ve_E21p*{&R${gKJ^+O60B#%3n5BQrAaqf z&&2UdVw$VT{wvVmv$AOS4@JWW327|9Z}(cyma&Hzhy0xFw91NU*I_S_`H>g%biz7U zh*EKD4lPyBqy0bZJP^Rh*n{Y%KX6LICZ5G%Y#T&@G!TUbIv~IaFbiLTK5W>0O3$Ou z5G8khxRvC3sO$@g*C@2OldY{2V&To>&<+%4gmrawU>0dbGMhQs94b8+vY+kzje@+eZjT_TSIMmtRVfdT8(r@d!D}e*c^AjQ4&O)&+bsg^ zfAq*c^$KQh2cq2Jl!wO+um%ZKsy%{q$X7+h2+;!X$u#S8ai#$#W=exHw@`pHZgpE% z%$H1Z4_IF#9<9jtp8e7YU}T)a$oZJlZ!0j2X3zXQP;Dl&~t)@fff zs`_d^_U_#qVz6wDQDPMIb6n0ntow(WY=hHDo38eza1(p{M4fyLr(Ota@fwCg>r8p~ zqUF?$*1O^$>OwOouhI?~GK84P0Ix94yJVXNp3Ov~25H%nfdyZO`ctSN3_fqF+20F& zAC_oT@7}$8LHh(%NS1X-ZXme#amg|r!a8%H8MRNc?c%jBcr95=SytbJ<|wsn-fZ;* z7@;f;9X4TTdPBS-Z4@DTsRYq&l~4$JHZmE?W#^6n8X+wvYe+=0+X(MZVD=%Ta_*jG zVcwuWz+6{$`SPc1t#^IgwW}s7uCmEwPGW?OgO78CkBpg!NFj1kbAL=E=%8V;j*^%5 z=0vo%Hv}@Q41x;WvPYtJeeC?4deY~K`$L%VHkqJy>eQRW%|aX9se&N)+jA=F`>1JR z10zZZb&H}OSNSID6TrqTv-xcdW3gDKr%x)Pua$Dq{*D^%Eh{T)a=VF^tgVDADn@7; z@(v>&uXAN=kkx?(^sO_^feygfX8)cMi(!+Yc>f|1D^y3%chcZ%Lj*>T9u0Al0c#x2 zyVMOl=sx|Ng#KfU?u+6BLz!udfv=-}2F~^oRLKiIN(VjyCGag`Rsd)m_Ct|{Hic8& zz%**I67YRcU?rttAiE|`b?8cg%!8POG#x5qY+%7J&Gz!X zs2E|bexeEk>4R>J5S^4}b0Pd6=`?_Dn(vyrN&9{rFW)OPO%cW%H+A`wP!3?14*?K^ zUVxj-QW0@TlJ)dGyevPu5@E!3Tad$F^W|9xKhk_eIs>W9BCauOPX6gq-f{$DNg8n# z%qfa7)Mi4$N!AF5v;tE4`JD}?gQ<0;QzvTkhZgfiTfy3k@&H2nuIJiJN}@H_Jz}Y+ zLt#KrE=C?K8nOo>Uti-2l)9pvfMAIXUNv+MUUt5eF8xfUwzgJiEw5pU`F)NZJN5-& zI9;^ABb6G^N~a<7C)xphi;5BcZ0JO?cJQvOy3-Feq*0d|?X=ZJ|9IykNf9{0$%%lg zwbm%fgCb_PvogH-HUj~O_4?q0$=W*M##`uPZ;Z$)BfEm#LR?463s`gV|JIYlLufq+ zYlM*5n?f^%Bu?ERVoQtg3s6IpcSN88pBY$r$yaHG>W0As319+?D03hn(eXp5&v0=f zZl1(Acy~@Zevf1@Ug)gAB(}oGN?~?~4lXm~;tTo^Zg{CFG* zCf|=1X;=W)EP|V-b4{upy(lV1h|i0t*BV%VafR5x<}8eWCOZl;@JJlQCn)j7R>TOe%Z%CJQD5Iik4bC5YIt4M6ViHGrUYCTA0Q@wDw&+5g9m9s5<( z=Zh$2_6yf1t1Iro`j+T=u9XsIouw!@MCD@nfHnyCWBYim{AZ#%Sf#5&;K^mEuh0n* z>3I3?$Y=xxeZR!oVBdy$<&Q(Yz&x3b(0{ng8>3DGiOu) zVAp6{m0;=@qaJg8E7Blg!|QA(5!~K*DOX1nRgmXkHy5e9tP*ZR4pF9`9fkH%{o6(EC=&2#9KiWKDLQ4 zqKv$oEODUi1)3KAC5YY_>ieP&Ve3jt6k$dPZAKU&kYJHVG>688!we1kfR!h~*kKJt zJPm}m)}h5?*dY-Q10z$gURHqu&6psXd_T8L*-X$9BO^%aIwd!J&}R%J{snp59i%@{ znZPuU0goX4J!sL|Z1|#Mgk6=xJMq!KFKaIA=lFV5O~n$meu0B}{nYMQH;}iu#&H5> zT*-E+9Mby8hTPW?%zQRu^KDodU`P%P-=yXo`(C zcIgwD!*XJR79*$Y^eI!O1jf!O>4XUrE=HYxiJSu~-5~G7SYr*+-<@pR{k7;AVP(a% zdW_4~g4wx(PvTMZsHtC0o;1Hgo|Zs2dyOSO z)vB2Vx0umLtb>T2U^IG#@YV?sl1*T6hlr^8IhyStTz3%u&-sOQdk@C(0GP(NgE2uT zHS@z2E0z;s7jh`8H60QOOmzd(NNH}1#DO`o3goc>(2dTlj{uZb^7g1FIeybJgKR4SP; z#Hq9?c2V6`x-E(%bk5!0}b&C8QqehK- zVdKV)8{ETXzrifB4Cy`s->;&K*)Ij2?7Go5gCNX}G!I2T9on`lPo6k&Vt)`;NMpPm z>OTd`WB-fv8)&7XdfO2jZRYKOLmVM$yhAm7i-E{sH{nutXsaLZgTeMd1G=lOx~l5= z=bzsKJTA;_t6Zi??}?$~`}!`Fla^o*=8K(EM(9e-!dT@gJj3vNW}hHj|&(g<8w;#7aGmHNV`Rlq?I0HMMZ0Q$p6JI>pmXeLaNWJG{1DIANVD zrK5yHeZtYi<&Ga;EhE0PA>GHAu#Hsmqr6bpjm;o-TblC+=7aQ=Pr0?x1s7aE+M+l` zK9f+mg$DVM&1(0z4d2i{N%YA@nQvUWs1?MfS8@+k)t(wPYQnJ0cy9L?^^XFkFCd>r zF+nF?tX&BcS&DJAJ0-BoBp*YZz=Kt^@gQf=;-r`FN@c*`?rqz)3D2S_9nxCI1%1K`IO>mf zpQN(jR{@6mBnA>>+tt$%zGKFWyBGC%1_66Jb+Ius$*LA%>zRi05|Hn3?)jRHKv6Qn zl4!|J5QEJM_6)i@Ffnx9PdM8s{(k8kQmcN|YwJbcw9r4%xjyZrlQ&EU^8~@cY1f`# zb}k}fUt(^ofX|qv64CjGTQnGr#<_M$52T2>edN8rC3KCAt(0@Byqxy@@m{QG~4hsDvH9x!sr@eFc4u1{Xf1 zwBGNAL_m1WlM)0I(U7+9Y}3gcb)wm6V23(9Zy0)mfxA6mpne86h=2CakaQiAC{vmN z43?dD-g%z_L+qNFDVVDQOa}tPTd`sORlxHgQh=1eW~RxoG()}*e!Kkfvtyu7RVU-} zB?kcyPLmU|1s^Mi4U65gW8-qH;Z1hS*4{25jZbc)sHSjO@mmPf>aHTyd}&$fDDwG7 zdxdC|{RIbZw4l?)MLsJwGIF^I|~td zQewIN42&0k#*1i(9=VUt`dSSqq1H zno?|*^WH4cUk78W3L+jwkCN1ID1uITvy)Cozv9EA8DUX5o3P4nz468yuCo@*7-2LT zRKmkiy@>GQcN9SbGs0xjkAdJp4P6{0Vqiqjkach5I~BiM!T7#~dff!SVJJ_8`ZR^h zbar*jC*X%QMzQ>mPaFoct1{E^ySL5bnac>9Adc!}*Gq z7+HOy9Ph5e+Vf5L%|U%9gONfZ#txTRdg>2gYHvlOk^3_Jz3%Ncl}|vkn;D@CP@Y7? zB~FWY>vcyqnY!_TpQsa`$hDQGY1L!N`Ew58`K2J+D5x^lCVj)4!+Q#?H4hv&BoA;# zwk^`w0-4yv)?DEg6hvaE*L!+r6D8~JFxF}I`i0N;9u`HmgD}&!2J5v=;PZuS=;sha zB7)A(CU_0QsyGM&BmWm;v2H)cTiWpM>!>UsdF%RCnnu6lx$yFwd|3U_FTuY-i|yG2?hay<5=HVZCZexDQBxt0IPAQf)riqD6~n zKiR-yt4NYixvmdVc@f5Ue;Rd*B(d7Hb?eqf5&a}K{|Tn?tUY6+Gz*IuF+nVezKS}1 zUR4hf1Hsy&4@I|%U=?I9M96_p7}&UR?OVv>1*cAhsu5uW!X8C>U%?>a(VTPz)^x3z zQQ+Ac+LVe^Rsi$WOV5;UhQl5S#vL#?I+i- zU;j_17VytZ!12zyCh^~m{lQH#lAe`lJ9`lBC9P3!S(TpG6ERousHHs`Dd{YQLpM6* z>w22G8mG0q?KhKj!aG-p(21ITdE!fd$Xd8|-glHMh$JH({m$5iFeo z62$zO^f8W>q8Uz52Zk&EJM!K~7!|@%T~Kx~81vI0;J?jH6VeCY?~RxU%G8MVQij+J zC^y&KXRCi5rtLAgZ-P9dPms9%W|Z}Vq$nTJbNN(5CP-z>{N?6pV`w5x`P#SNe*2A_ z_r9WK5H|FEb4OCcH77bh5&}id2us58H_e3czSrh@n$1bNaZ_bg70qO%`NQVKupa#f zQkx6nXip*53eW6XTKdT#@!Db7f%qtW#Yrt$Zz9T&B)(Z)UG2L0oz73h2k*Ld!lvs) z+=(byzb5agA|{1>jk7`cpeSM47HtwNN#;`z(b)H+(dZ3Zwru&B5|rf-S^3F(a(r%v zb{b}*MPT-9!@L=!`AD)nxmgH36W%rfr-6bz16Vzq8<8v+fk4C5S}wClhop4y{xH_J z4yJuY@62+qv@=sdxLt)fMvN3^P~WRDGh9ca^GpmKW@qPX*V&`$h)ZoxecyPVFa)Dr zompnONBk^}+}!u{oGe3=`+L5$+lyZ?ZqdTEuIx9y7A^g(*P5SB3@oIbQzsq0*ePBl zqCI2AV*AN*Ob};%G=}tzS#NgSSs|8ND~)FC=Oi_ ze+l~FB^x%Z`%$LY7WPw5MSBQ!X6nO8uSP8Q{Gq_K7DMsqCcJ&uE?bcL*!>2@*atD* zy};%ZAmE$x<@C-w@2DWtU7S3qU2=a(Z1zLcdpKVjZhp3zKTn~{+?hA9B!!&xGwbBs+w~`g zsT8EYyOg2Ld%G{d6-m_$MSf0?#=eb)#fUgh&w(HI8!9+s@QWz&5-Ro!uo83GE6+WL z8Qz!mC@oEhIeS(ZKF6q&KZ6*s=hyL^qL|Q5G`|R}0d_;Y^EH7eN{x-1fSw@;^Kzej z4q(=J8<>VG)rOX)l>|oXRJ|2G=?TA1GOb5oM(i0?4c&rS&b5eqjzf$nA%c^b9brKJ zwzI@!2T{A_VB}9$R8%aCA}KtEzsaqad=E! zzFeDB-t!flA9!IRnqRj8=GLgNC*qPi@v(u!-l2z?%bq(ACWQZiju1|Mz2xodX!Z$) zSRLsany_g6Rn(c;F#>@Qz&^unhM|lGQ=SZ}HVl366wp7i4~eOV4C^f>M4s|4FqYL2 zt**klPqkMDqeqXO3+0)+iJ@=*{`!C}aC z*^0j|P(z_>t@8~nPqBYsx{?u%-M{3L>wh2?gF`U_-UtjEHY^M=q1>%oHv_W;+RQKP zuvz=h5P#j|#|UjED4hh;97k(a!Wje)DC2mja3m5jGex+;lj-m=WGJxE&wqr|;h}0? z0NMm2ymQZcy+YCY^*DuofOYaj9!#(SpQitNqEcx5Ps`8!h=N@9_XU^Anz9&T1~reA zFHb7Amvt(IX<#3gF?s2<8{c&e$S)Xy=0||cZT$n{yYoqA=H+ZgXx88`+KG;$jaPVn z#|SV2HUdHm@U0EjWBtxL03tA7358sXLMKv$A|?I8M(j&YpqRR8IfOTV_loC)&Ai&i zxWnBgL;jH^%+Gwu_l!UbA~1RKfg}!JsE7_@~Pu7=iYUK$~EMRuh9!lQhZ>? z2($_USVP46ocJC>6mnnC6BJsdVw@=>P(%o{8AdpF(6}wowOWidKUet3fHr1@6`e~< zKj#GMelWhwOz5u!ofVRT4Hm9t#V{Y5x_l9o1K2SFEsp>gVPAB^GLf7Sj)K*Qgyk@d z03(n_pv^Es(ls_r{TEmxgw~z=(x!nUP9R3Qr zBgU#kLT84|cxBp`?-+rWLjX$xFcKgMZKk(NWmdOb={P4wpnV|Fb{HY>t}fq3r%Sx1 z;-qpnN6Iu>NeS#ShOvjpc1x$<@R||VpTQx#j+gKiCtyf0*Y@ShmOsZLQeo6MV4)C@ zW$iTDFde{E2MEhS839HB2n71VS{t$XGG=#*{5WQPIF;9ZR%kIVS-$<-)f+2PWmZE! z#=758m~2RS3EfzldU6QU(Vt$qY~JZYaX1hoP#^?k*%%<26t-7D4PUb~rbXj$I7WaG zXk(0!8mzSH;NP(3_YciuR!H_owMe9wX3F_lCC$&aC8BR%t8A9kQ5SvR%XX;~Huq{KXb-e8`>I8YgcKKYHUR;HdvZL*&{?b_$`xIV8j ziZj^Kti}^!s_gB!&v4aR2mx4#=>ee!j@hxqo+7!{hy>y=i~u8$jX;}Zgj9tG2M&J& zCrp4b)S@Lo#_D@(PS6k$W$IT-U} z^B{l|CwigZk#TFwIoEu-*~Z}MUw>GJol!SuZ?cb^ zYHG&Al`#KK;a;Bh$!arUeuqZdUfQRbXkkBviuT>uakwea30b3tr#& zC+s)hd`TVgak`eHh+<*uixag$)2W;_`yu6{J_8O+)QVINp$py5;E^JV$n^C zhtdsE9&DYEjClNy2jAa6kK(dp1X=%KE6Lh1Nlovsu$3Ga8vpqoOTbxNrbW-YrM|8x=)={p87$tT@*w zB#SSSb^LSj6-&HCKdl&ZBSX}_qHCsgEl=1{adl+@8 zKpm~K`0&|c@(W#WQ{Jnp@;mTWlYQgrN0pN_fKvMHD4582OX9 z`UoukG;D~bWRQ$Y_#8ZVu*=zJpM7lp{P{$X*flc(ZJrSlJ`a|UTzt=tjeiW4m3%f{ zSMLg00wPkaByv@Kb^RR(G?xPY?Xnv`xcc>lGo$sfFG`wn9T@5`d|?`nZ#rojvGtHR z{rBH5x&CHyl#D%rBo>9)d3%i3V7v$aG@6p_{s?6N8o*X=F{*c%@EVhdf0Q;S!cPA0@H!B?sQ!zt<-*4k3=8W zKgfF7j1S-?F)K@aS}4N`T~GWT*XQy3fF_A3Qzy*0ZV82=kI~v(zM?<@ydA*Qd=C-J5H)nQBPV!~I9?zPozEeVVNOAHE``!H_vw7wgd7 zP^e7N%-`O#ee1NjgNN;Os%f88Asu#}`N{~iCIXtKZHdL=yD$?OkUa|_#+M$O;XM`e z!^ViwC~ZV90V6zIR#sMnbY#rL27@6%45;keuwlb~N<8UgDAZUAB7+7Ein`=yg~1+3 znHaN67$-gF`Y`fYOb-($PV5?u#w)=L?jX~tDBE?57A^WQUTt>*+gBMgSkqOxXY}aN zLs2*DJ<_S~(WA!)D^{#Hk)1~N6Y5rmdY_4UpK6+FZ73w~U9)D*``Mw~pN0$>66w~h zo7$yI7h>EAmN^8JJ_%01XH)IO?Oe|+uQOs&h=3 zFk+BtMh2t*bVB~Sx_0gQ{u^(+aXeowNF;msaP1%zp%?ld8FHvYS$9XH(Ra6Q-5Se{ zbN>0~_rW@82<47ZKcNB3k|j$@B2OA(U$dNvi(qJ9e$KKJ2FC%W;bnfxD_UjQ;MP zcdomqdef}C_rKevI7{hXs+B8O?!((>6-6b60B8M6M#$D61@Zha`6AE-gsuX_m&T5J zK=5XP@V<@&HiNirfd86NqsG!Qf|W4{r3!-jXZWv%*zWWBG8!{x{J+q9Rn?wBn9lja zb=5P#5=zow;ogL1k?~}y0LJkaY^w_cE7NGoVP^Xpj1AcEEJ$n32F!)=L zNG6D>H1X~xA~_PX+WCgpAi1T8{u~(5TeY?I ztKk1>J5>5V{B8k8Z>Xxi2IAQ_5a${EUPOquN=izWp^Q_~p(Sbd?AdC4ef*hlI6`eb zf6SQkM!odXOMgW^Z^0Dhf zeY;|WmFT@jZT)w!UE)2j1AGbaL_O9EBjH)$M5hN^vjI5o!XxnQZ5xN*Q}y z|DTZNmvO}`lh$GN6DU(0ey3p#__JU--vyJP8Q?I)?~AKLlQjwhrg1v_Xf|eXNBEJo zp?)Y6+Q$3}{2xKG*hT`wk*4%d3P8R7`csBuBw2Kh#DhwW?VDb=mC#XEL zFk_q#rua0%or~Fa6loK-7~IHrS5;Nb$xg5Jo*d9yuLK3o`H^Ag?KSnp*8p}sTHP~s z9VXadUFIA2ZhxCbz3kdJ0^ixWaX2)Hf2(TpN}Ne~GjtF;#cS&%GPMUKsR@!|K2cd! z)uz^!-g@gTh(;wE^(R35l1woBioTB5YE5IB4^bfs16h)#2-0~dk%*6mnCn^)%*i0y ze*-baJL9X)=pALi41@BM&&1W5r8xO^?%a7g-j4+lJeEkre(Cu8U6D**5*^YH1o}p# z@e{-$hKq~&KZJo_8W&t}K^GM37l_+CNo-$5ou;9T6OqPGa0OK-1}A?Pd0gbAhZ)%z z`2P^ksEfs@o<-0r5qB2q|8o#;Y}JsyXNM<#)zCrY_y8EzB!UIupT{$aa={;r8K}by zT=8h`LAuw~*DGft%%uNs?@ZvVsIL59Rd4CnvTve@A_@wqEP@(MR1g&*A|mK$T*eqD z|Li(0xK7e0e+4m#n#D={PjsR&iHvL-7f=@CMigus{;e2+Zd4Qn6h!Fmx7B=4y?)K> z=Jlhy1#IM3ADXJVb+`Ify?g4Md+xmqRrxV{ykk>S5guss{w2wze?1Ya?0Im$o;cr6 zCexQw_uDPRHoFfihrKx`A z1{(Ne8;@!6ZKEE4O{Eg|P=^aC;sow}DEUty{#wp)XbRbw)(bPSv;X@kyEo#Qz(1Jh zeyx>5+IuoAl3epn=b8!DF`cO@;vMGTSY;K$>E#-Cf^ zT5sZE)!}U{+U%^%z1G@~>8F~-K<*#Vfc=8Ttc^83CWC1Bf;|ltx9-2w-21?672dr0 zQ{!Rz{JymG^_#MJm^O#@^hfeN!-QUCWn~Ypy-V5UwF2q@%v)Uu3%nYwf9UbYAO9YW zol65hefjd`tFw6(+S^Z%`?w!rVA6tP7inYKjZc4`|5JqWU4_zTuWj90JrXuUNkdv^ zV=@`KV)^pdvUMmMGUV9)To#pgVNGWe;Q%IM@Hs;(iKaWF2!^hY#;Fd>u8L> zB5ZSQ*k2LQrs>^E{9^Ll5|6igsJy)Keog8f=GouRJx!v|_A~km)8yHKXY{YNLNLzt zTPWj=+A{u(RyP_`<|Qb}`x7>bzX$9Zao%RvP$4L%PD6-Goow^^W%il>GtVw_%q#iJ z($Xcrv@_ldOxx+JxfgqmXtVymEnd9%>Dp_5;r%(@-eESLSL@iml!DOEZrYf*qf=*R zXrwqcmTA};rEShLXpS-03;n-qS1tYU7l#iHzN#8cP~gIua~^8rMT?K~Be5QCJo#bF zb(YK;F@95lB)Zf>0+Uv}*e+Dmek5ygUB(aXtZ*b+oJ0T?de&AH&L@S<1TC!3?oNg< z{5`_(Z5oluG<-pyRi-hq2H2~PM#Ie(gqW}}QTaIH(Db_g!iM)iBesR>791gNph;sY zT)`KAf)w2m1ZK($1mX1Qj}Hlloih-E)zs@h8|GE$oCdSj3~I4Vz?({B8k{$fhWj`g z>DLOS4^p}55j5B)1npj4$q|Bf*@ius5ITzn+D=b4Gj7kGJyZ1MjWi)vTjsPJA!zBG z#)Kf3647XMFiEZPrycdTa^K&5EgLrXL`<;MA^iXv+p9Q{tZQgGMz9rA zmyABhJ{sL@{iAsud<+rgtxY82KgN+}GkFE25H^Uif{z;l-fh#SO}(+0lws}LB^H?? zOb|U_$Jx!ebne`_S4~YCZ{nm?o_=A|`po~(Z&Y4j)_o$I2k!{0UffAeZ^kZFLP*V{uz+IKps#Rn@lBXu`h1-(xg*^y9hKuvGH*X>;q1_hBdU zU~qcCZ3jV`ZIsE^=ba8(bo!CjkmdtxwD~(ETP8yA-_VAlJc4JMBDk{Y0-5JH)(1C; z@{XgZOKHsKaNeG4mr%wW96xsGkIbguz7I^bfj}dlitXWbN2c*)w+?uAw%@X43uaWm z3uOl3l>1gTLKF7%ojLbV$DSD>>P+LlpUq8&zsLfj--?6F zYkc6m=6UIVkdHYI-4tY%iIxFXnm#?HO48- zvCL!2q8Fk5p6mYg%!RY>Fm17^`6=FZ0@H9Iys2VYKZM_pZhB|=b9}qM6p6)t!dTD& z_5ov)BxHW{+tcJ8*@Wy^1swW=SEhaUy1NfPsa1ZF=GM8;@v>#hwjvP!!r%Gy>kOk` zrjPIMHym%vErrtMy9T#jgrkKxn`ofd?-(a^kTv3L+h`mEK|6Z%Xfs*Bcm>aQg z4IOF%aU!0PXkPwrEUcN^N}ELnGw5RWe~QOz&Y?~S5!2MXPFMgNn(Xpq@3+ed+?I13 z9O77#%n1twJLXf;xOIKT+-sd0lM}bG!vt-5sR_~A_wSVc{f8cy8`*{q@O-{SU*AuN zw;BNfALHrL-{xJ+!F&YNw{p`o=NQ&28ph|jgtmvdZMmmW$VJ8`X8yQ-%=YVeU*q|4j zWZJ$s(|nT^L~hPAXpjA{IXpgTb=i>xBWEx2TTLWW*Dzmc*L2PcV3%3y$qYPRC=$NO ziMD(4w0YB8q-|!4+E?~hSCn>~^j_IlZd|?eKVE-l`FwiBmPBGj_j=*TY5Y)&nOl|* zjofx^M>6)TO#re~*T*d4d`B|no;i)@eLn_rvTp1QeQX{VkPpJ7hx;20j{0G8**}?%81)!Bx}p zn!3>!nz#em7MN{$FAtB!(vuq|whtHj&VI@eh#@R~GYV}CN0RhM8LiC4^y%JZlXy2w z*V1$D3$r!3+EdLqx?ISuo}2x{tbH!e>0HV`kL!UG4xXJ8Oi&U|n)GVYo;+^cxKrpe z9?kJR^14?y?}d7t(#fV$%h^D@b#;f_NFnt%``urcB4529)?BH{;r#vfhICx za_@mVe0Aj}{_0D!+hR-qS~?lLf4P@3$CQ-{R=?=@ZMSWy>Bk4dG3k_#r=2^L@Ao4@#YHyzBtkE-gY!!^ZNt53{$>j2Id4oRl7GUT z;J(Q{kNIcAcsjQ}Cg%_ajq`JG*G-r(VKe<=nao+~{vMOb;R&q@G`uJHIGNrs zjg5~a>{h5= zi3bpdg(Gs+grOG>5AZ|YjBDRo)~`^4NFt3X!i({|&23zkcJIv20e=*3@Etgs*s!=mYfSeFJl*Y2&Vq^+cOP ztK0eS&!*O6$b@10AQ?~G?ZlHOO*#0et0(syEFsv)%S6L=s9mD5tjK73+auz{`4hB+ z?lkfr6c-mYkU*hw^Gf6q9l)@=%V|iN*(9|bt?o?{=Zo`;)1-MVRZ@jq66#Gdv)2eSfopJ%=Py>DCPJE`EkFu z7jo&#^7~aepC0M?k*;pUYj2ucV2%m6@Bva_s7pQsX8yE^6RckrTi1$II{qgbm4|LW z=$Lo&#aGyN0@g^+nl-zxDIEv~kH(q--r=o0qXXjc$ zvuSByYb>1!3&O8t9+__RZQV9@?ARA(&whLs!#5`IPMOK^AsYPuCgOS;bA*}K&jcRV zR+8?ImP76Kd%`Z~8q=FOhrr@l(k-MMYUZ3u4fjWwZ9}V?olVei52xEG<4p26l#hZw zkw{SqalXrNlApo!W*y-9_Gi&InZJ3LJwDC;ii;W0;6bJ-ri{wBQ9k zJjO6d!e_*NjjCKpJ&EFvhv`(F!7A?SeC}tYeUQ|?3&Y9hMC$QMp*n28w)aTGeMS)4 z!znrHsL%fW-SSI|;x&(>J$%*rnhI^EjUcpoN8Iqt8&)p+)}4I@+RIdLGZW{i`7`h1 z$8@S|U$0HjUMyc4@lI$!lcNc5;+YE{yKV09iA^=h)GL2ao>;%B8^(+jPquNwVN7D_ zBG>V{QHM@^5O?Os(&hEaW&7iT&^?`qb#vTcdaPKq4eb&eKGhkaMe7GICtYBrkRU-L z|C#pZg;*dY9^Xb^;R`rJJ-9Ww_32;t{Yv1_(MU1{=Mccm$a>aAhgcAT;bI!y^XMmp zpW6lRPsZA%OsL&z&MP^|f_;xq?4toC%7he)%;t`u8412p>(lN#sL(6X-5~ znTc=+Tq|OKeKszAi?n%eg0OSgA4r}1b1f?fgJ(!Mb*-Bb z$Al)$TV@yxykjT`nF^DTvTVj2i<2#)RqXdEL1@J9KKQ7QuUYx(MG@C~49)QPooR-F zFpNYF#H9IG^IXK?;*SlV+?)~T{?DidGy1rp$WNWHkAGTW&Ct>ZS_}fwi$sQ|Q_k$O z7S5WERx^3d$O#$ae8WP%z;hf|dWO>8FL-&!@^M&f>onpaON~P28EZn_eha}zKyY8C zq1mTCFT1_&iK?p4U3*N`X08rQr3k-rCz+bbNBfK^y#|+l?#%bW49p<~P3KbDtkZd} zC($Ydy-$Tslc>n@*BIPryicONw+B0k> zQ1E~p$I?=l)8LNhT6cmy_FIVa3=Q)AIIp~CadS5W*>gu9J@nK_By}Y(GJVtz8d;zb zR#3(?gur7KpJlEnE12>Q8@yk|7`@FFZriwVXPfZp$)Ry%b2{-6aVtW0Rx0ID*VG7D zwdXonI-5CuE}c$3Tvk?A&vbvzIp^HV0>GQe;Bq4F4-eCT7gL=FtQ?pv#B3cQjGtKg zB@1h~@ljw*Z$YTeL-=3Du?bW24z4EMTXs(fqsOUVV3IYbEBY<*LJl)Mo_{97FvdN6 z%JFRaK!3yhrXId&H}PCfr26x$JR7`^=4jfqeF)6lMx-Iw>o6yVoc;78GvzEjJpBoMZ&PEjS7Q>?Fp=HjDeHL0|+Wl@R zcpuFa(`W<}T9KK`nu34^{s#IGr_d0-ACHHImY2U~{a$-)v;M2@-MdE{TS>txLgU_s z!QpOG@2R%(F2b}eV=Pn6G4(d(#)l6dZUWY6YJI3jJNo=;?4zYA`8O7aa>F)x0{2wC zGiRo3T)5hM(7M#N#%^#IgzvM0(AeFuX6aFgpjqK)w9n3FB(eCW`B>x37{NcrJolOs zv`Y)m-A;dYMt|nI{56{1NOSQIG^5-I1&)Kp-#i}UiA{X^JCSz+W57E--1T7U&dp!VXVf_1A%KAVoi;iUS_#|^1eAEFL<@_ z6ua-rEfq_?lJG+>V&s!T9hItYF_c>XF3&9J1$bF$W+3xL< z-o5M0D!Zm+<gfNU+OHq|Ioetq0ZgGIBa!HHW-Y_9!aOhUU{#0*TU$L<9}#E? z0SUrdYLnhs(Zfr}A7&ieX|*dA?3AaO@i3yN=qbLBIVyfKW#B;TOs}_nb@uFbZ962d z#f$D#VOT>p9uSPU3W2uBUy|7ymJ7nWKCGLoN&Jg*s zR@fI$0LL2EzYAT;hs`pq11~bg+r}@xR;qyr>>2_RggG2bnA)q_4c#9qDmve0gRzEv zXPap}#AiCS#H$SCzUHnzL-KlZov~o%VmTvh000f7NklxA5|TN;~wttFdz zY|>w6>92}BtY0SKta<}=OZ+)hp z;Lx%Gf6@<9p1;nChc^3(Pd=I2?`zWZb^xaU5fFjaKtO`9!BZ%ySP-jnJN-Nqj($Ho z?yW(Tyr-;opYi%+{=RDOvwQPR?tK2VX`wCMA{XIZeIo+xs6fMOp%=0BtFiie#?**& z4d*YSf6ZZp&cZG0ldE32;DXOTW+CsL?w-IBzr=g_?}HCwOyCiWl&Y@!^s_f!Jp1Au zH0<3|x^fi(5!jarNDwyi^f3os?fLGVtY9BaHBo!BelX_CG_TKBQhxHLyLun{e7@|z z{6km@(x(`o?-R$)mJ3uZ(t>uA-CdcPYPm>Rr8$&pXCy%)IHnlA+L5 zJcLV`Ev0K_wTc~vCl;t-o=euBXoKAO!y(1-lj*Glt)T1f4gCBTvn|N+#%Y7#a((hp>#hd>7RhWW1?aANHp2*Hd9Q{zlak})*Ky-+oa++ zBwhXNi1GLC@=7T~5fA|ps3jmlxRY1mhE>asaU<^itbqQNgbk8!LcgJ9S=VKWj?Xw zz+jevt{XbF^NXWx5aAs|zS9wta#y?xS@6~EUHLoIT^sjGH8hN!Au<$ENE1W$JzmRr zWC_V*%GzL1NVaU*w;qiwWgGjbF_}V^>{%L1XpG5HV;RO4*?YhGE8ZWTbDdw$ecktc zKA+EhU*|g4Ici|%uqez$hsykOk-t1w)Z{_`|xQu}qHRt!|=JJ$&=J3p25>3Fl z97na|#C9H(8@bx0+;<&jf|InygZtCWv3l~k=!cQ-vbKd@eWQjO*Xp+M8-8WH--j1O zR4aN%MVua)jtx%O_QSFvunFY}9}$RJz3w(-oQr}^u1L!8PTf9XOE|*}i@XglCM-wa zNntT`P{VYLJu14_6t6n-NR;=Xv{pR0`eEM1C^O9;{MNtHQ~1C{^(yrxk1H788e>_^ zizb+Aj`cMq%%JC7kUa(0n{%-U^fVI0FCn38&tlR3Uxcl~hmTtyt$BQIzd*?;!+^7$ zu^^AlDXn%rw;(g0j>geX8fY3ZTGILZW3~Z=i8?vYm7L7sWy#5)6b0}lW|P@aA3mH^ z4z@}6y#;sUCfVALv$vRWz1;te#JtI(I6Ua3j(iUN9^j4x8|bhZNI;@a)i@Rib5t5n z(-Vi=7LhwNq^f_S{Dxx>(M}O20}b$$;Py@zg%4#i<%wQ<6EX!8wGHM6fuFY&q}FdB zc$qz;-YT8BCWUcdBX$RY3;COhvmxK}X66JR@A@Ev&a+CAML;*W>!)R%>}maQ=tVL@q(i@vsfRzLwTzXzBPPj&Y{Tq0!Y1lg%%JYwxwB?RBIRi#m&AlLsB(_b7O>NpXX>)H`uE~dTK`IJ~7WX!vD(^ ztt8ChYE4i&8zZ1`w0L1^-STBPQ*>aa^4&4L$!7sw9w_`rhWSfN&Udm|?ohuvILqFH zgdzt`IO!U=I>xcH$HhH&GS{92kA5)r(GK*3ek53lE-aK4$ZZrSNR9Yx+{|+r?63%B z-S?rp%uZIWVy#Y$paU3L^IAc6NQs^MZX%o9%AAOQXfc+9xgH-P0-8pn11xgZ+L&^V zyNQtiW_Z#isD`UioOLdHMBc8>6w*oAn%}PhtXSVHwn?r~y615AE1=N7d5t)-Sum*TAB?)Me&QuK0}c!I8x$ zHSv@>Ma&Z$;!tbi)hDv>7)ki8de3y|h}ZPt*DLL;^U@RP{vcH@f<7Gd$*VN^4pEoC zT7~Bk#IygMVNe1iwA9ScSt;UYOSMWFmh~$m^O#o4D!^7X{s-MVnM4`qUkSQ^VvUGV z8B6+`FK0bc{&HV`JanXjy|d#Kv7r={S9S%~+=M~7?jE+sp}oDvP(m6*Z{>0p=!SZl z`FAthnBl%LNJxpjU5Bl^n-(M4<9^yrucT7J-Yx@ltO^|>Q=qncQ))q_n1PlY=*Bb9 zI^}q&YTn{`QyDS*&*I)K<%&TDH18V$+I{AW{`fKdUc~}Rvv0jK+#&Kk|KouORCleg=!^3h+0@J-JrT7VB>hJ)qa6VmIP@A8ltY@sdi` zWlck^p$>0NsHfq!~1Blf9Mtj!Al> z>KvnQrpVCtuCO+5_B#E92VTi;q+Smbd&>~VcRTHJITV{8-8T6)Ekf)GI=Jf!^txh> z*@}v>34pcMW<8xJYiELo5w*@VO#y!e1N$((5ak{X!lh27=1W68Y9b?DI_tBZEX&^k0|r ziDft>ymkl_5HfauYWt=nHDq?`^tmQGdHViIt?L5vtdeUNBqekwOvUM(-r3?m%BB*k zg;aTBSITc#Wr$)`lzf>qP7<;UDqS@f2ojA|rZ{sHKd1Zz!NB-`JYLZyEnG5b0* z0&}x85P{-@FWlE6_uSkPO-_b|H=-mSs|p5SdFDw$;@8(s*MQ?IrH+?2=Cd&4C=S4- zDTr2Ye^$NQOjFe*Q*}W#COfF&4OYprFu+$w)s{b*ab}Mn-GJ?Xru1@EuqQeKt$jz@ z6mVLCHB<)RsqF#PtNX-YVPZhDoinW-jq%bUNMo++t$QaMYou0C8{!t{`tW*Iq#ZPT zRn`xO8Qu^_OCt=0fNJW`o$eW^7?z5NcslQyqK>WTOT9;(HZdF5oLHaonXxDK#93Sk z+1g$l;P6Oo<5)}Bp&&cd*SDinLxL1L3%&l}AqnV->VBCkR z0x9QWbe0XZ=Z?T~%V$%Kme`G}!Y+bPBE-OhPwEh{jk}BnsV_!s09&@fKp>j!yJuue zONu0I#b{$A=I0@1@zn5e3bgB>M1S#?h6oJWM%?ot;P$kcOX~N(2>qoiAa|UFf9Jm$ g_`k@&>m>FAMWTLhJDXM^FAFeC3@r@sdM;1?2V+N deployed to your very own sidechain. @@ -23,7 +23,7 @@ block masthead | Join the Community i.icon.right.chevron - a.ui.huge.primary.right.floated.button(href="/contributing/", style="margin-top: 1em;") + a.ui.huge.primary.button(href="/contributing/", style="margin-top: 2em; margin-bottom: -2em;") | Join the Community i.icon.right.chevron From 1e68efbf352b2905f147eb07bc7a6ee2c091c583 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 29 Mar 2017 03:41:19 -0700 Subject: [PATCH 09/31] Improve Liquid visibility --- source/sidechains/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/sidechains/index.md b/source/sidechains/index.md index 59ec2e5..ca9131e 100644 --- a/source/sidechains/index.md +++ b/source/sidechains/index.md @@ -85,10 +85,10 @@ These sidechains are in development and testing, or are explicitly intended for ## Production Sidechains These sidechains are being used on the main Bitcoin network. -
- + @@ -78,7 +87,7 @@ open-source reference implementation for sidechains.
- +
@@ -94,7 +103,7 @@ open-source reference implementation for sidechains.
-
-
- +
+
+
+

[Liquid](/sidechains/liquid)

From f16122fad385859e2f886cac4adfc4e112897037 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 29 Mar 2017 04:07:07 -0700 Subject: [PATCH 10/31] Add selective disclosure, confidential addresses --- .../confidential-transactions/addresses.md | 50 +++++++- .../confidential-transactions/index.md | 108 +++--------------- .../selective-disclosure.md | 79 +++++++++++++ 3 files changed, 142 insertions(+), 95 deletions(-) create mode 100644 source/elements/confidential-transactions/selective-disclosure.md diff --git a/source/elements/confidential-transactions/addresses.md b/source/elements/confidential-transactions/addresses.md index 3a8b8d9..48ceb00 100644 --- a/source/elements/confidential-transactions/addresses.md +++ b/source/elements/confidential-transactions/addresses.md @@ -2,5 +2,53 @@ title: Confidential Addresses --- +The most visible implication of Confidential Transactions is the introduction of +a new default address type, confidential addresses: -TODO: explain them. +``` +CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi +``` + +The most obvious differences are that it starts with ``CT`` and is longer than +usual. This is due to the inclusion of a public blinding key prepended to the +base address. In the Liquid wallet the blinding key is derived by using the +wallet's master blinding key and unblinded P2PKH address. Therefore the receiver +alone can decrypt the sent amount, and can hand it to auditors if needed. On the +sender's side, ``sendtoaddress`` will use this pubkey to transmit the necessary +info to the receiver, encrypted, and inside the transaction itself. The sender's +wallet will also record the amount and hold this in the ``wallet.dat`` metadata +as well as the ``audit.log`` file. + +``` +$ elements-cli validateaddress CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi +> { + "isvalid": true, + "address": "CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi", + "scriptPubKey": "76a91448a67bbdaf57b6f55b50f02fcaacfa079900853588ac", + "confidential_key": "02483237addc73befdb9b851f948c1488cbb7cf1a59ba8af36be1c479e0f6e8bc7", + "unconfidential": "QTE8CaT6FcJEqkCR4ZGdoUJfas57eDqY6q", + "ismine": true, + "iswatchonly": false, + "isscript": false, + "pubkey": "0347b013d415f7dc964cfadd0bb0627c48ae6ae27a58cdd37d71990eaf8f38c60c", + "iscompressed": true, + "account": "" +} +``` + +As you can see the unconfidential P2PKH address starts with a `Q`. P2SH start +with `H`. Most RPC calls outside of ``getnewaddress`` (e.g., ``listunspent``) +will return the unblinded version of addresses. If you provide an unconfidential +address to ``validateaddress`` it will show the confidential address. + +You **must** use the confidential address in ``sendtoaddress``, ``sendfrom``, +``sendmany`` and ``createrawtransaction`` if you want to create confidential +transactions. Therefore, when you want to receive confidential transactions you +must give the *confidential* address to the sender. For all other RPC's except +``dumpblindingkey`` it does not matter whether the confidential or +unconfidential address is provided. + +
\ No newline at end of file diff --git a/source/elements/confidential-transactions/index.md b/source/elements/confidential-transactions/index.md index 9c7c2b4..a606830 100644 --- a/source/elements/confidential-transactions/index.md +++ b/source/elements/confidential-transactions/index.md @@ -21,113 +21,33 @@ be undermined. -#### In Practice +### Using Confidential Transactions The payment flow when using the Confidential Transactions Element is nearly identical to Bitcoin Core on the surface: ``` -elements-cli getnewaddress -XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq +$ elements-cli getnewaddress +> CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi -elements-cli sendtoaddress XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq 0.005 -82b2c5122207e5f33e7adadc6a4aab16a170e16028f0b0cf2c04f9d17d6f0321 +$ elements-cli sendtoaddress CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi 0.005 +> 82b2c5122207e5f33e7adadc6a4aab16a170e16028f0b0cf2c04f9d17d6f0321 +// ^ this is the transaction id ``` The key difference from Bitcoin is the addition of cryptographic privacy. These transactions differ in that the the amounts transferred are kept visible only to participants in the transaction (and those they designate). -#### Confidential Addresses -The most visible implication of Confidential Transactions is the introduction of -a new default address type, confidential addresses: - -``` -XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq -``` - -The most obvious differences are that it starts with ``XoR`` and is longer than -usual. This is due to the inclusion of a public blinding key prepended to the -base address. In the Liquid wallet the blinding key is derived by using the -wallet's master blinding key and unblinded P2PKH address. Therefore the receiver -alone can decrypt the sent amount, and can hand it to auditors if needed. On the -sender's side, ``sendtoaddress`` will use this pubkey to transmit the necessary -info to the receiver, encrypted, and inside the transaction itself. The sender's -wallet will also record the amount and hold this in the ``wallet.dat`` metadata -as well as the ``audit.log`` file. - -``` -elements-cli validateaddress XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq -{ - "isvalid": true, - "address": "XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq", - "scriptPubKey": "76a91448a67bbdaf57b6f55b50f02fcaacfa079900853588ac", - "confidential_key": "02483237addc73befdb9b851f948c1488cbb7cf1a59ba8af36be1c479e0f6e8bc7", - "unconfidential": "QTE8CaT6FcJEqkCR4ZGdoUJfas57eDqY6q", - "ismine": true, - "iswatchonly": false, - "isscript": false, - "pubkey": "0347b013d415f7dc964cfadd0bb0627c48ae6ae27a58cdd37d71990eaf8f38c60c", - "iscompressed": true, - "account": "" -} -``` - -As you can see the unconfidential P2PKH address starts with a `Q`. P2SH start -with `H`. Most RPC calls outside of ``getnewaddress`` (e.g., ``listunspent``) -will return the unblinded version of addresses. If you provide an unconfidential -address to ``validateaddress`` it will show the confidential address. - -You **must** use the confidential address in ``sendtoaddress``, ``sendfrom``, -``sendmany`` and ``createrawtransaction`` if you want to create confidential -transactions. Therefore, when you want to receive confidential transactions you -must give the *confidential* address to the sender. For all other RPC's except -``dumpblindingkey`` it does not matter whether the confidential or -unconfidential address is provided. - -In order to execute a third-party audit of transaction amounts, the blinding key -can be exported by the receiver and passed on to the auditor. - -``` -elements-cli dumpblindingkey XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq -5fd02f714d52b68bbbfef3b8e6d83be646fad1de5150e83d26a28496e00a2146 -``` - -The auditor may then import the address and blinding key with -``importblindingkey`` to observe watch-only amounts. - -``` -elements-cli importaddress XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq -elements-cli listtransactions "*" 1 0 true -[ -] -elements-cli importblindingkey XoR8jNLkTr7VmSTRxWh1pizJgcXX6cuDD3nxNpeGAEmvitWuZ6eDzJcnVbUCtko6LAxVvqTuPhFuXTJq 5fd02f714d52b68bbbfef3b8e6d83be646fad1de5150e83d26a28496e00a2146 -elements-cli listtransactions "*" 1 0 true -[ - { - "involvesWatchonly": true, - "account": "", - "address": "QTE8CaT6FcJEqkCR4ZGdoUJfas57eDqY6q", - "category": "receive", - "amount": 0.00500000, - "label": "", - "vout": 1, - "confirmations": 35, - "blockhash": "708f969b4fb1c705b82fa3ed309abc7a3d9b0e87aa6e5d17542bb7ee04c8e1f1", - "blockindex": 1, - "blocktime": 1488223140, - "txid": "82b2c5122207e5f33e7adadc6a4aab16a170e16028f0b0cf2c04f9d17d6f0321", - "walletconflicts": [ - ], - "time": 1488223140, - "timereceived": 1488225018, - "bip125-replaceable": "no", - "blindingfactors": "0000000000000000000000000000000000000000000000000000000000000000:71260137a80039dd8cee330d9f7bba625697dc53098cf54d625242946f26997b:" - } -] -``` +
+ +
+

Confidential Addresses

+

Confidential Addresses may be new to you. Learn about Confidential Addresses »

+
+
The ``createrawtransaction`` API in Liquid works similar to Bitcoin's raw transactions with the following differences: diff --git a/source/elements/confidential-transactions/selective-disclosure.md b/source/elements/confidential-transactions/selective-disclosure.md new file mode 100644 index 0000000..af78a9e --- /dev/null +++ b/source/elements/confidential-transactions/selective-disclosure.md @@ -0,0 +1,79 @@ +--- +title: Using Confidential Transactions for Selective Disclosure +--- + +The [Confidential Transactions][confidential-transactions] element offers cryptographic privacy over the amounts of an asset used in +transactions on a sidechain. There are many use cases for selectively disclosure some parts of +a transaction, for example to an auditor. + +### The Blinding Key +The "Blinding Key" is a shared value between the participants that grants them +access to the cryptographically-concealed amount. By sharing this key (out of +band), external parties will have the ability to "decrypt" the transaction. + +In order to execute a third-party audit of transaction amounts, the blinding key +can be exported by the receiver and passed on to the auditor. + +#### Retrieving the Blinding Key for a Particular Address +``` +$ elements-cli dumpblindingkey CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi +> 5fd02f714d52b68bbbfef3b8e6d83be646fad1de5150e83d26a28496e00a2146 +``` + +An auditor may then import the address and blinding key with +``importblindingkey`` to observe watch-only amounts. + +``` +$ elements-cli importaddress CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi +$ elements-cli listtransactions "*" 1 0 true +> [] + +$ elements-cli importblindingkey CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi 5fd02f714d52b68bbbfef3b8e6d83be646fad1de5150e83d26a28496e00a2146 +$ elements-cli listtransactions "*" 1 0 true +> [ + { + "involvesWatchonly": true, + "account": "", + "address": "QTE8CaT6FcJEqkCR4ZGdoUJfas57eDqY6q", + "category": "receive", + "amount": 0.00500000, + "label": "", + "vout": 1, + "confirmations": 35, + "blockhash": "708f969b4fb1c705b82fa3ed309abc7a3d9b0e87aa6e5d17542bb7ee04c8e1f1", + "blockindex": 1, + "blocktime": 1488223140, + "txid": "82b2c5122207e5f33e7adadc6a4aab16a170e16028f0b0cf2c04f9d17d6f0321", + "walletconflicts": [ + ], + "time": 1488223140, + "timereceived": 1488225018, + "bip125-replaceable": "no", + "blindingfactors": "0000000000000000000000000000000000000000000000000000000000000000:71260137a80039dd8cee330d9f7bba625697dc53098cf54d625242946f26997b:" + } +] +``` + +You may also inspect an address in full: + ``` + $ elements-cli validateaddress CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi + > { + "isvalid": true, + "address": "CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi", + "scriptPubKey": "76a91405d5c237c5f2d90cfa22a22b75a1d1c1ede021a088ac", + "confidential_key": "03b0f93d729839d3d96bfd7e20f11c7c6ae2016644d0d4cded6332dbfb61ed9067", + "unconfidential": "2dZxbqgzXvANyj9SmyRR9LX3R2k8hg4iUWa", + "ismine": true, + "iswatchonly": false, + "isscript": false, + "pubkey": "031f17ad1acce63acf2d04cc59cb24423ab30f9345dd17476fd2380b02f878295d", + "iscompressed": true, + "account": "", + "hdkeypath": "m/0'/0'/10'", + "hdmasterkeyid": "f5ff0a90ac04830fde2f952cae9e076f9c2b4d39" + } + + ``` + +[confidential-transactions]: /elements/confidential-transactions + From 8f3cf1d5c5f39e7b28bd69041e07277e8be59b83 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 29 Mar 2017 04:32:43 -0700 Subject: [PATCH 11/31] Improve asset issuance instructions --- source/elements/asset-issuance/index.md | 55 ++++++++++++++++++++++++- source/elements/index.md | 6 ++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index 19e78d7..6971951 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -20,13 +20,66 @@ regulatory requirements). These assets can optionally be "blinded", causing the data in the transactions (including amount and asset type) to be cryptographically obfuscated in such a -way that only the participating parties can see. Particpants may choose to +way that only the participating parties can see. Participants may choose to reveal a "blinding key", which grants visibility into the transaction. This opens the door for building trustless exchanges, options, and other advanced smart contracts involving those arbitrary assets and a "hostcoin". ### Issuing Assets +Use the all-new `issueasset` RPC command. Here, we're issuing 1000 new tokens, +and creating 200 "reissuance" tokens. +``` +$ elements-cli issueasset 1000 200 +> { + "txid": "13a2357b0a51114fae92127f7afc74847acf07f87e1bb4849715d1c75dbc9a92", + "vin": "0", + "entropy": "4dcc890a6fc4f593c609ffaa295940acb244904c1439aa9cb9d8192440b41da4", + "asset": "8854427e5ffcb0b837e85832b901b1135cc4ac766f537e2a7f07b71a76c5b9cf", + "token": "ca270d5552e81d15e4f45e41ff2d9c7e456599a7678286b80f8b41cae179b26a" +} +``` + +It may be convenient to create a name for this asset using `addassetlabel`. This label can be used in place of the ID for all asset-compatible RPC calls. + +``` +$ elements-cli addassetlabel 8854427e5ffcb0b837e85832b901b1135cc4ac766f537e2a7f07b71a76c5b9cf funcoin +$ elements-cli dumpassetlabels +> { + "achievement": "aef740ae340f3abbb620699fc243021572c2e9d966f88f98ba26999ddaa54d34", + "bitcoin": "09f663de96be771f50cab5ded00256ffe63773e2eaa9a604092951cc3d7c6621", + "funcoin": "8854427e5ffcb0b837e85832b901b1135cc4ac766f537e2a7f07b71a76c5b9cf" +} +``` + +#### Re-issuance +Re-issuing an asset is effectively a provable inflation in the asset type. To +do this, use `reissueasset`. Let's issue 20 of our tokens: + +``` +elements-cli reissueasset 8854427e5ffcb0b837e85832b901b1135cc4ac766f537e2a7f07b71a76c5b9cf 20 +{ + "txid": "6b20c853521346d5bda3fe9e006292260cf409054224f920f3abf6297aca8176", + "vin": 1 +} + +$ elements-cli getwalletinfo +> { + "walletversion": 130000, + "balance": { + "funcoin": 1020.00000000 + }, + "unconfirmed_balance": { + }, + "immature_balance": { + }, + "txcount": 1117, + "keypoololdest": 1490389457, + "keypoolsize": 100, + "paytxfee": 0.00000000, + "hdmasterkeyid": "f5ff0a90ac04830fde2f952cae9e076f9c2b4d39" +} +``` ### How it works All outputs are tagged with their asset identifier. Consensus rules are modified so that the total inputs and outputs are checked separately per asset. diff --git a/source/elements/index.md b/source/elements/index.md index 9db5276..e3a6e3d 100644 --- a/source/elements/index.md +++ b/source/elements/index.md @@ -17,7 +17,8 @@ edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/s Elements is an open source collaborative project where we work on a collection of experiments to more rapidly bring technical innovation to Bitcoin. Elements are features that are proposed and developed in this technical community that in arbitrary combinations can be fashioned into sidechains. ## Current Elements -These are the features under currently under investigation as part of [the Alpha developer sidechain](/sidechains/alpha). +These are the features under currently available in [Elements Core][github], the +open-source reference implementation for sidechains.
+ +[github]: https://github.com/ElementsProject/elements +[liquid]: /sidechains/liquid From f3e73047b4be9fb7ab610c0132ed8aee72a41b4b Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 29 Mar 2017 04:38:47 -0700 Subject: [PATCH 12/31] cleanup formatting for asset issuance --- source/elements/asset-issuance/index.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index 6971951..54f855f 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -82,16 +82,25 @@ $ elements-cli getwalletinfo ``` ### How it works -All outputs are tagged with their asset identifier. Consensus rules are modified so that the total inputs and outputs are checked separately per asset. -A new transaction type is added for creating issued assets (asset definition transactions). Like coinbase transactions, asset definition transactions (the new transaction type) have a null input, but unlike coinbases, asset definition transactions have more inputs in addition to that first null input. This difference not only helps us distinguish between the two: it also guarantees a source of entropy for the asset id (which is the sha256d hash of the transaction). Within an asset definition transaction, any number of outputs with 0 as asset ID can be included with any amount and they will be treated as the initial unspent outputs for the newly created asset. +All outputs are tagged with their asset identifier. Consensus rules are modified +so that the total inputs and outputs are checked separately per asset. A new +transaction type is added for creating issued assets (asset definition +transactions). Like coinbase transactions, asset definition transactions (the +new transaction type) have a null input, but unlike coinbases, asset definition +transactions have more inputs in addition to that first null input. This +difference not only helps us distinguish between the two: it also guarantees a +source of entropy for the asset id (which is the `sha256` hash of the +transaction). Within an asset definition transaction, any number of outputs with +`0` as asset ID can be included with any amount and they will be treated as the +initial unspent outputs for the newly created asset. -This technology is similar to colored coins in many ways, but explicit and consensus-enforced tagging has many advantages: +This technology is similar to colored coins in many ways, but explicit and +consensus-enforced tagging has many advantages: * Supports SPV wallets much more efficiently. * Allows more complex consensus-enforced contracts. * Benefits from other consensus-enforced extensions (ie confidential transactions would not be compatible with colored coins on top of Alpha). * Opens the door for further consensus-enforced extensions that rely on the chain being able to operate with multiple assets. -Currently only the hostcoin can be used to pay fees, but it should be possible to pay fees of different asset types simultaneously. -In this first version all units of a given type must be issued within the asset definition transaction. In future versions it will be possible to define assets with a dynamic supply that can be increased after the definition, allowing the issuer to create new units. -Future versions can also implement consensus enforced interest that would be interesting for p2p lending and issuance of assets with built-in demurrage (negative interest) among other things. +Currently only the hostcoin can be used to pay fees, but it should be possible +to pay fees of different asset types simultaneously. From d9a2f2ada6923f9d3acace34b0a5ac95da686fba Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 29 Mar 2017 04:40:47 -0700 Subject: [PATCH 13/31] Add minor CTA on sidechains page --- source/sidechains/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/sidechains/index.md b/source/sidechains/index.md index ca9131e..ad8e3be 100644 --- a/source/sidechains/index.md +++ b/source/sidechains/index.md @@ -26,7 +26,7 @@ edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/s
# Featured -Sidechains with a working network can be listed here. +Sidechains with a working network can be listed here. Add Yours » ## Experimental Sidechains These sidechains are in development and testing, or are explicitly intended for non-production use. From 3d82635490e07477b20b7336458aa80ed1826b74 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Mon, 3 Apr 2017 15:17:30 -0700 Subject: [PATCH 14/31] Confidential assets subpage. --- .../asset-issuance/confidential-assets.md | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 source/elements/asset-issuance/confidential-assets.md diff --git a/source/elements/asset-issuance/confidential-assets.md b/source/elements/asset-issuance/confidential-assets.md new file mode 100644 index 0000000..1a400c4 --- /dev/null +++ b/source/elements/asset-issuance/confidential-assets.md @@ -0,0 +1,180 @@ +--- +title: Confidential Assets +description: Extend security to multiple asset types while obscuring which ones are in use in specific transactions. +--- + +## Summary + +*Principal Investigator: Andrew Poelstra* + +The security of any blockchain ledger comes down to public verifiability of +two properties of every transaction: that they are authorized by all required +parties, and that they do not affect the total currency supply. In Bitcoin, +the latter property is so simple to check that it often goes unremarked: add +up the total output amount and total input amount and compare them. With the +development of [Confidential Transactions (CT)](/confidential-transactions/), +however, this security property is front and center, as it must be preserved +despite all amounts being cryptographically blinded. + +Several blockchain technologies have gone beyond Bitcoin to support multiple +asset types on the same chain. This allows a wider set of users to share the +security properties of the same chain, and also enables new use cases, such +as multi-asset transactions which effect atomic exchanges. Enabling this is +as simple as labelling each transaction output with a publicly visible "asset +tag"; however, this would expose information about users' financial behavior, +undermining the privacy benefits of CT. **Confidential Assets (CA)** is a +technology to support for multiple asset types while blinding all asset tags, +preserving the privacy of CT while extending the power and expressibility of +blockchain transactions. + +As in CT, Confidential Assets allows anybody to cryptographically verify that +a transaction is secure: the transaction is authorized by all required parties +and no asset is created, destroyed or transmuted. However, only the +participants in the transaction are able to see which asset types were used +and in what amounts. + +In a multi-asset chain, it may make sense in some contexts for assets of a +specific type to be created or destroyed. This is accomplished by means of +*issuance transactions*, which create new asset tags and a specified amount +of this asset. Later reissuance or deissuance may be done by proving ownership +of *issuance tokens*, which are related (but distinct) assets. Issuance tokens +may be created alongside a given asset type, or not, if the asset should not +support reissuance. + +Issuance transactions are unique in that they are not required to balance to +zero. However, if they issue a public amount, it is still verifiable that +exactly this amount, no more and no less, was actually issued. + +## Technology Behind Confidential Assets + +### Asset Tags and Rangeproofs + +To describe the technology behind CA, we start with the (Pedersen commitments +that [form the basis of Confidential Transactions](/confidential-transactions/): +``` +commitment = xG + aH +``` +where `G` is a standard generator of an elliptic curve and `H` is a second +generator for which nobody knows the discrete log with respect to `G`. We call +such a generator nothing-up-my-sleeve, or NUMS. + +In CT, this was described as committing to `a` coins with a blinding factor of +`x`. We observe that if we refer to the generator `H` as a coin we can read the +term `aH` algebraically as "`a` coins". When `H` is our only generator this is +merely a semantic trick. But suppose we add another NUMS generator `I`, and +consider the two commitments +``` +commitment_1 = xG + aH +commitment_2 = xG + aI +``` +Now we can think of `H` and `I` as representing two distinct assets, and we see +that these two commitments, while committing to the same amount, are commitments +to different assets. + +Consider now a complete transaction with two inputs of distinct asset types +and two outputs, like so + +``` +in1 = xG + aH, H --\ /-- uG + cH, H = out1 + |---| +in2 = yG + bI, I --/ \-- vG + dI, I = out2 +``` +In CT, where we had only one generator, we required the equation +``` +out1 + out2 - in1 - in1 = 0 +``` +to hold, which it would if and only if the transaction balanced. As it turns +out, this same equation works even with multiple assets: +``` +0 = out1 + out2 - in1 - in1 + = (uG + cH) + (vG + dI) - (xG + aH) - (yG + bI) + = (u + v - x - y)G + (c - a)H + (d - b)I +``` +Since `H` and `I` are both NUMS points, the only way for this equation to hold +is if each individual term is 0, and in particular, if `c = a` and `b = d`. In +other words, this equation holds only if the total amount of asset `H` is the +same on the input side as on the output side **and** the total amount of asset +`I` is the same on the input and output side. + +This extends naturally to more than two asset tags; in fact, it is possible to +support an unlimited number of distinct asset types, as long as each one can +be assigned a unique NUMS generator. + +As in CT, this simple equation is insufficient because it is possible for amounts +to overflow, effectively allowing negative-valued outputs. As in CT, this can be +solved by attaching a rangeproof to each output, in exactly the same way. The only +difference is that the verifier must use the appropriate asset tag in place of +the fixed generator `H`. + +### Blinded Asset Tags and Asset Surjection Proofs + +The above discussion assumed every transaction output had a NUMS generator, or +asset tag, associated to it, and that outputs of the same asset type would use +the same tag. This does not satisfy our privacy goals because it is visible +what type of asset every output represents. + +This can be solved by replacing each asset tag with a _blinded asset tag_ of +the form +``` +A = H + rG +``` +Here `H` is an asset tag from above and `r` is a secret random value. Anybody +who knows `r` can tell what asset this tag represents, but to anyone else it +will appear to be a uniformly random elliptic curve point. We see that any +commitment to a value with `A` is also a commitment to the same value with +`H`, so our "outputs minus inputs equals zero" rule will continue to work +when validating transactions: +``` +commitment_A = xG + aA = xG + a(H + rG) = (x + ra)G + aH = commitment_H +``` +The introduction of this blinding factor does not affect the user's ability +to produce a rangeproof, though it does make the algebra slightly more +complicated when constructing the transaction to balance out to zero. + +However, since every blinded asset tag looks uniformly random, how can +verifiers be sure that the underlying asset tags are legitimate? It turns +out that the "sum to zero" rule is not sufficient to prevent abuse. For +example, consider the "blinded asset tag" +``` +A' = -H + rG +``` +Any amount of the blinded asset `A'` will actually correspond to a _negative_ +amount of asset `H`, which an attacker could use to offset an illegal +increase of the money supply. + +To solve this problem we introduce an _asset surjection proof_, which is a +cryptographic proof that within a transaction, every output asset type is +the same as some input asset type, while blinding which outputs correspond +to which inputs. + +The way this works is simple. If `A` and `B` are blinded asset tags which +commit to the same asset tag `H`, say, then +``` +A - B = (H + aG) - (H + bG) = (a - b)G +``` +will be a signature key with corresponding secret key `a - b`. So for a +transaction output `out1`, we can use a ring signature (proof that one of +several secret keys is known that keeps secret which one) with the keys +`out1 - in1`, `out1 - in2`, and so on for every input in the transaction. +If `out1` has the same asset tag as one of the inputs, the transaction +signer will know the secret key corresponding to one of these differences, +and be able to produce the ring signature. + +The asset surjection proof consists of this ring signature. + +### Future Work + +Because algebraically, Confidential Assets is such a straightforward +extension of Confidential Transactions, many of the tools developed for +use with CT can be used with few modifications with CA, giving them the +power to confidently and confidentially handle multi-asset transactions. +Examples of such technologies are + +- ValueShuffle (add link, also check with Tim if the name has changed) +- [MimbleWimble](http://diyhpl.us/~bryan/papers2/bitcoin/mimblewimble.txt) +- [Scriptless Scripts](https://download.wpsoftware.net/bitcoin/wizardry/mw-slides/2017-03-mit-bitcoin-expo/slides.pdf) + +We are looking forward to the future, as many exciting developments +continue to appear. + + From 92175cb4bc62215b585692de6d8c61b78574a5e2 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 4 Apr 2017 15:13:19 -0700 Subject: [PATCH 15/31] Swap information messages to focus on new content --- source/elements/asset-issuance/index.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index 54f855f..eee2b9b 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -8,8 +8,8 @@ edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/s ---
-

Looking for the original investigation?

-

Read Jorge Timon's original investigation to learn about the origins of this Element.

+

Want the cryptographic breakdown?

+

Read Andrew Poelstra's deep dive on Confidential Assets.

Users can issue their own confidential assets which represent fungible ownership @@ -104,3 +104,8 @@ consensus-enforced tagging has many advantages: Currently only the hostcoin can be used to pay fees, but it should be possible to pay fees of different asset types simultaneously. + + \ No newline at end of file From 917217089db6ac2b38e2113610c0ac267e012e28 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 4 Apr 2017 15:18:37 -0700 Subject: [PATCH 16/31] Replace text with @instagibbs' suggestion --- source/elements/asset-issuance/index.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index eee2b9b..ced4dee 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -82,17 +82,14 @@ $ elements-cli getwalletinfo ``` ### How it works -All outputs are tagged with their asset identifier. Consensus rules are modified -so that the total inputs and outputs are checked separately per asset. A new -transaction type is added for creating issued assets (asset definition -transactions). Like coinbase transactions, asset definition transactions (the -new transaction type) have a null input, but unlike coinbases, asset definition -transactions have more inputs in addition to that first null input. This -difference not only helps us distinguish between the two: it also guarantees a -source of entropy for the asset id (which is the `sha256` hash of the -transaction). Within an asset definition transaction, any number of outputs with -`0` as asset ID can be included with any amount and they will be treated as the -initial unspent outputs for the newly created asset. +All outputs are tagged with an asset commitment. Like CT, the consensus rules +are such that instead of checking that amounts are balanced, the value +commitments are checked for balance. A new transaction type is added for +creating issued assets (asset definition transactions). Asset definition +transactions have explicit `assetIssuance` fields embedded within transaction +inputs, up to one issuance per input, which denote the issuance of both the +asset itself and the reissuance tokens if desired. Embedding issuances within an +input allows us to re-use the entropy as a NUMS for the asset type itself. This technology is similar to colored coins in many ways, but explicit and consensus-enforced tagging has many advantages: From d139359a93a97531ed7a92c2228202b84c474d90 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Mon, 3 Apr 2017 15:17:30 -0700 Subject: [PATCH 17/31] Confidential assets subpage. --- .../asset-issuance/confidential-assets.md | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 source/elements/asset-issuance/confidential-assets.md diff --git a/source/elements/asset-issuance/confidential-assets.md b/source/elements/asset-issuance/confidential-assets.md new file mode 100644 index 0000000..1a400c4 --- /dev/null +++ b/source/elements/asset-issuance/confidential-assets.md @@ -0,0 +1,180 @@ +--- +title: Confidential Assets +description: Extend security to multiple asset types while obscuring which ones are in use in specific transactions. +--- + +## Summary + +*Principal Investigator: Andrew Poelstra* + +The security of any blockchain ledger comes down to public verifiability of +two properties of every transaction: that they are authorized by all required +parties, and that they do not affect the total currency supply. In Bitcoin, +the latter property is so simple to check that it often goes unremarked: add +up the total output amount and total input amount and compare them. With the +development of [Confidential Transactions (CT)](/confidential-transactions/), +however, this security property is front and center, as it must be preserved +despite all amounts being cryptographically blinded. + +Several blockchain technologies have gone beyond Bitcoin to support multiple +asset types on the same chain. This allows a wider set of users to share the +security properties of the same chain, and also enables new use cases, such +as multi-asset transactions which effect atomic exchanges. Enabling this is +as simple as labelling each transaction output with a publicly visible "asset +tag"; however, this would expose information about users' financial behavior, +undermining the privacy benefits of CT. **Confidential Assets (CA)** is a +technology to support for multiple asset types while blinding all asset tags, +preserving the privacy of CT while extending the power and expressibility of +blockchain transactions. + +As in CT, Confidential Assets allows anybody to cryptographically verify that +a transaction is secure: the transaction is authorized by all required parties +and no asset is created, destroyed or transmuted. However, only the +participants in the transaction are able to see which asset types were used +and in what amounts. + +In a multi-asset chain, it may make sense in some contexts for assets of a +specific type to be created or destroyed. This is accomplished by means of +*issuance transactions*, which create new asset tags and a specified amount +of this asset. Later reissuance or deissuance may be done by proving ownership +of *issuance tokens*, which are related (but distinct) assets. Issuance tokens +may be created alongside a given asset type, or not, if the asset should not +support reissuance. + +Issuance transactions are unique in that they are not required to balance to +zero. However, if they issue a public amount, it is still verifiable that +exactly this amount, no more and no less, was actually issued. + +## Technology Behind Confidential Assets + +### Asset Tags and Rangeproofs + +To describe the technology behind CA, we start with the (Pedersen commitments +that [form the basis of Confidential Transactions](/confidential-transactions/): +``` +commitment = xG + aH +``` +where `G` is a standard generator of an elliptic curve and `H` is a second +generator for which nobody knows the discrete log with respect to `G`. We call +such a generator nothing-up-my-sleeve, or NUMS. + +In CT, this was described as committing to `a` coins with a blinding factor of +`x`. We observe that if we refer to the generator `H` as a coin we can read the +term `aH` algebraically as "`a` coins". When `H` is our only generator this is +merely a semantic trick. But suppose we add another NUMS generator `I`, and +consider the two commitments +``` +commitment_1 = xG + aH +commitment_2 = xG + aI +``` +Now we can think of `H` and `I` as representing two distinct assets, and we see +that these two commitments, while committing to the same amount, are commitments +to different assets. + +Consider now a complete transaction with two inputs of distinct asset types +and two outputs, like so + +``` +in1 = xG + aH, H --\ /-- uG + cH, H = out1 + |---| +in2 = yG + bI, I --/ \-- vG + dI, I = out2 +``` +In CT, where we had only one generator, we required the equation +``` +out1 + out2 - in1 - in1 = 0 +``` +to hold, which it would if and only if the transaction balanced. As it turns +out, this same equation works even with multiple assets: +``` +0 = out1 + out2 - in1 - in1 + = (uG + cH) + (vG + dI) - (xG + aH) - (yG + bI) + = (u + v - x - y)G + (c - a)H + (d - b)I +``` +Since `H` and `I` are both NUMS points, the only way for this equation to hold +is if each individual term is 0, and in particular, if `c = a` and `b = d`. In +other words, this equation holds only if the total amount of asset `H` is the +same on the input side as on the output side **and** the total amount of asset +`I` is the same on the input and output side. + +This extends naturally to more than two asset tags; in fact, it is possible to +support an unlimited number of distinct asset types, as long as each one can +be assigned a unique NUMS generator. + +As in CT, this simple equation is insufficient because it is possible for amounts +to overflow, effectively allowing negative-valued outputs. As in CT, this can be +solved by attaching a rangeproof to each output, in exactly the same way. The only +difference is that the verifier must use the appropriate asset tag in place of +the fixed generator `H`. + +### Blinded Asset Tags and Asset Surjection Proofs + +The above discussion assumed every transaction output had a NUMS generator, or +asset tag, associated to it, and that outputs of the same asset type would use +the same tag. This does not satisfy our privacy goals because it is visible +what type of asset every output represents. + +This can be solved by replacing each asset tag with a _blinded asset tag_ of +the form +``` +A = H + rG +``` +Here `H` is an asset tag from above and `r` is a secret random value. Anybody +who knows `r` can tell what asset this tag represents, but to anyone else it +will appear to be a uniformly random elliptic curve point. We see that any +commitment to a value with `A` is also a commitment to the same value with +`H`, so our "outputs minus inputs equals zero" rule will continue to work +when validating transactions: +``` +commitment_A = xG + aA = xG + a(H + rG) = (x + ra)G + aH = commitment_H +``` +The introduction of this blinding factor does not affect the user's ability +to produce a rangeproof, though it does make the algebra slightly more +complicated when constructing the transaction to balance out to zero. + +However, since every blinded asset tag looks uniformly random, how can +verifiers be sure that the underlying asset tags are legitimate? It turns +out that the "sum to zero" rule is not sufficient to prevent abuse. For +example, consider the "blinded asset tag" +``` +A' = -H + rG +``` +Any amount of the blinded asset `A'` will actually correspond to a _negative_ +amount of asset `H`, which an attacker could use to offset an illegal +increase of the money supply. + +To solve this problem we introduce an _asset surjection proof_, which is a +cryptographic proof that within a transaction, every output asset type is +the same as some input asset type, while blinding which outputs correspond +to which inputs. + +The way this works is simple. If `A` and `B` are blinded asset tags which +commit to the same asset tag `H`, say, then +``` +A - B = (H + aG) - (H + bG) = (a - b)G +``` +will be a signature key with corresponding secret key `a - b`. So for a +transaction output `out1`, we can use a ring signature (proof that one of +several secret keys is known that keeps secret which one) with the keys +`out1 - in1`, `out1 - in2`, and so on for every input in the transaction. +If `out1` has the same asset tag as one of the inputs, the transaction +signer will know the secret key corresponding to one of these differences, +and be able to produce the ring signature. + +The asset surjection proof consists of this ring signature. + +### Future Work + +Because algebraically, Confidential Assets is such a straightforward +extension of Confidential Transactions, many of the tools developed for +use with CT can be used with few modifications with CA, giving them the +power to confidently and confidentially handle multi-asset transactions. +Examples of such technologies are + +- ValueShuffle (add link, also check with Tim if the name has changed) +- [MimbleWimble](http://diyhpl.us/~bryan/papers2/bitcoin/mimblewimble.txt) +- [Scriptless Scripts](https://download.wpsoftware.net/bitcoin/wizardry/mw-slides/2017-03-mit-bitcoin-expo/slides.pdf) + +We are looking forward to the future, as many exciting developments +continue to appear. + + From 81a9755f5d45f3cafc58d715310d1521caea16bf Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 4 Apr 2017 15:13:19 -0700 Subject: [PATCH 18/31] Swap information messages to focus on new content --- source/elements/asset-issuance/index.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index 54f855f..eee2b9b 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -8,8 +8,8 @@ edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/s ---
-

Looking for the original investigation?

-

Read Jorge Timon's original investigation to learn about the origins of this Element.

+

Want the cryptographic breakdown?

+

Read Andrew Poelstra's deep dive on Confidential Assets.

Users can issue their own confidential assets which represent fungible ownership @@ -104,3 +104,8 @@ consensus-enforced tagging has many advantages: Currently only the hostcoin can be used to pay fees, but it should be possible to pay fees of different asset types simultaneously. + + \ No newline at end of file From bc1e7f0891645d8f201c41e4fce7eb94c12da182 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 4 Apr 2017 15:18:37 -0700 Subject: [PATCH 19/31] Replace text with @instagibbs' suggestion --- source/elements/asset-issuance/index.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index eee2b9b..ced4dee 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -82,17 +82,14 @@ $ elements-cli getwalletinfo ``` ### How it works -All outputs are tagged with their asset identifier. Consensus rules are modified -so that the total inputs and outputs are checked separately per asset. A new -transaction type is added for creating issued assets (asset definition -transactions). Like coinbase transactions, asset definition transactions (the -new transaction type) have a null input, but unlike coinbases, asset definition -transactions have more inputs in addition to that first null input. This -difference not only helps us distinguish between the two: it also guarantees a -source of entropy for the asset id (which is the `sha256` hash of the -transaction). Within an asset definition transaction, any number of outputs with -`0` as asset ID can be included with any amount and they will be treated as the -initial unspent outputs for the newly created asset. +All outputs are tagged with an asset commitment. Like CT, the consensus rules +are such that instead of checking that amounts are balanced, the value +commitments are checked for balance. A new transaction type is added for +creating issued assets (asset definition transactions). Asset definition +transactions have explicit `assetIssuance` fields embedded within transaction +inputs, up to one issuance per input, which denote the issuance of both the +asset itself and the reissuance tokens if desired. Embedding issuances within an +input allows us to re-use the entropy as a NUMS for the asset type itself. This technology is similar to colored coins in many ways, but explicit and consensus-enforced tagging has many advantages: From 69acefd3a9adfe51dbb837ae210fb6d66ef407b7 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 4 Apr 2017 19:25:02 -0700 Subject: [PATCH 20/31] Remove `addassetlabel` TODO: remind @instagibbs about being able to set this from RPC --- source/elements/asset-issuance/index.md | 13 ++----- .../confidential-transactions/addresses.md | 2 +- .../confidential-transactions/index.md | 24 ++++++------- .../selective-disclosure.md | 36 +++++++++---------- 4 files changed, 32 insertions(+), 43 deletions(-) diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index ced4dee..14998a1 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -40,17 +40,8 @@ $ elements-cli issueasset 1000 200 } ``` -It may be convenient to create a name for this asset using `addassetlabel`. This label can be used in place of the ID for all asset-compatible RPC calls. - -``` -$ elements-cli addassetlabel 8854427e5ffcb0b837e85832b901b1135cc4ac766f537e2a7f07b71a76c5b9cf funcoin -$ elements-cli dumpassetlabels -> { - "achievement": "aef740ae340f3abbb620699fc243021572c2e9d966f88f98ba26999ddaa54d34", - "bitcoin": "09f663de96be771f50cab5ded00256ffe63773e2eaa9a604092951cc3d7c6621", - "funcoin": "8854427e5ffcb0b837e85832b901b1135cc4ac766f537e2a7f07b71a76c5b9cf" -} -``` +You can add convenient names for these assets by passing `-assetdir` to Elements +Core, which accepts a `hexidstring:label` map of the assets to their labels. #### Re-issuance Re-issuing an asset is effectively a provable inflation in the asset type. To diff --git a/source/elements/confidential-transactions/addresses.md b/source/elements/confidential-transactions/addresses.md index 48ceb00..88711f6 100644 --- a/source/elements/confidential-transactions/addresses.md +++ b/source/elements/confidential-transactions/addresses.md @@ -11,7 +11,7 @@ CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi The most obvious differences are that it starts with ``CT`` and is longer than usual. This is due to the inclusion of a public blinding key prepended to the -base address. In the Liquid wallet the blinding key is derived by using the +base address. In the Elements Wallet, the blinding key is derived by using the wallet's master blinding key and unblinded P2PKH address. Therefore the receiver alone can decrypt the sent amount, and can hand it to auditors if needed. On the sender's side, ``sendtoaddress`` will use this pubkey to transmit the necessary diff --git a/source/elements/confidential-transactions/index.md b/source/elements/confidential-transactions/index.md index a606830..266a068 100644 --- a/source/elements/confidential-transactions/index.md +++ b/source/elements/confidential-transactions/index.md @@ -49,7 +49,7 @@ participants in the transaction (and those they designate).
-The ``createrawtransaction`` API in Liquid works similar to Bitcoin's raw +The ``createrawtransaction`` API in Elements works similar to Bitcoin's raw transactions with the following differences: 1. The intent to create a confidential output is indicated by using a confidential address for the destination. @@ -70,14 +70,14 @@ elements-cli sendrawtransaction $TX ``` ### Limitations -The implementation of Confidential Transactions in Liquid has some important -limitations to be aware of. The CT implementation only hides a certain number of -the digits of the amount of each transaction output. The exact numeric limits -will be set once the production Liquid network is ready, but they will work as -follows: There will be a 'minimum confidential amount' that will be a round -number of BTC, probably around 0.0001 BTC. There will be a 'maximum confidential -amount' that will be 232 times the minimum amount, probably around -500,000 BTC. +The implementation of Confidential Transactions as it appears in Elements has +some important limitations to be aware of. + +For example, the implementation only hides a certain number of the digits of the +amount of each transaction output, dependent on the range proof's "blinding +coverage" at a desired precision level. Subsequently, there is a 'minimum +confidential amount' that around 0.0001 BTC, and a 'maximum confidential amount' +that is 232 times the minimum amount. Digits smaller than the minimum will be revealed to observers; for example, if the minimum is 0.0001 BTC, a transaction output of 123.456789 BTC will look like @@ -88,10 +88,8 @@ values can be rounded to the minimum to avoid revealing information in this way if preferred. A transaction output larger than the maximum will reveal the order of magnitude -of the amount to observers, AND will reveal additional digits at the bottom of -the amount. (Technical details: The minimum amount will effectively be 'raised' -such that 232 times the new minimum is large enough to cover the -transaction.) +of the amount to observers, _and_ will reveal additional digits at the bottom of +the amount. For example, if the maximum is 500k BTC, then all outputs under that amount will look the same, but an output between 500k and 5M BTC will be diff --git a/source/elements/confidential-transactions/selective-disclosure.md b/source/elements/confidential-transactions/selective-disclosure.md index af78a9e..d343d07 100644 --- a/source/elements/confidential-transactions/selective-disclosure.md +++ b/source/elements/confidential-transactions/selective-disclosure.md @@ -55,25 +55,25 @@ $ elements-cli listtransactions "*" 1 0 true ``` You may also inspect an address in full: - ``` - $ elements-cli validateaddress CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi - > { - "isvalid": true, - "address": "CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi", - "scriptPubKey": "76a91405d5c237c5f2d90cfa22a22b75a1d1c1ede021a088ac", - "confidential_key": "03b0f93d729839d3d96bfd7e20f11c7c6ae2016644d0d4cded6332dbfb61ed9067", - "unconfidential": "2dZxbqgzXvANyj9SmyRR9LX3R2k8hg4iUWa", - "ismine": true, - "iswatchonly": false, - "isscript": false, - "pubkey": "031f17ad1acce63acf2d04cc59cb24423ab30f9345dd17476fd2380b02f878295d", - "iscompressed": true, - "account": "", - "hdkeypath": "m/0'/0'/10'", - "hdmasterkeyid": "f5ff0a90ac04830fde2f952cae9e076f9c2b4d39" - } +``` +$ elements-cli validateaddress CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi +> { + "isvalid": true, + "address": "CTEwQjyErENrxo8dSQ6pq5atss7Ym9S7P6GGK4PiGAgQRgoh1iPUkLQ168Kqptfnwmpxr2Bf7ipQsagi", + "scriptPubKey": "76a91405d5c237c5f2d90cfa22a22b75a1d1c1ede021a088ac", + "confidential_key": "03b0f93d729839d3d96bfd7e20f11c7c6ae2016644d0d4cded6332dbfb61ed9067", + "unconfidential": "2dZxbqgzXvANyj9SmyRR9LX3R2k8hg4iUWa", + "ismine": true, + "iswatchonly": false, + "isscript": false, + "pubkey": "031f17ad1acce63acf2d04cc59cb24423ab30f9345dd17476fd2380b02f878295d", + "iscompressed": true, + "account": "", + "hdkeypath": "m/0'/0'/10'", + "hdmasterkeyid": "f5ff0a90ac04830fde2f952cae9e076f9c2b4d39" +} - ``` +``` [confidential-transactions]: /elements/confidential-transactions From ba05ad3f112ed092ec1ec7cbbb74cfbec42422b9 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 4 Apr 2017 21:29:17 -0700 Subject: [PATCH 21/31] Change mentions of Alpha to "enabled by default" --- source/elements/index.md | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/source/elements/index.md b/source/elements/index.md index e3a6e3d..c13c434 100644 --- a/source/elements/index.md +++ b/source/elements/index.md @@ -18,7 +18,11 @@ Elements is an open source collaborative project where we work on a collection o ## Current Elements These are the features under currently available in [Elements Core][github], the -open-source reference implementation for sidechains. +open-source reference implementation for sidechains. For projects built with +the latest version of Elements, such as [Liquid][liquid], you can expect them to +support each of these features. + +For a list of proposed Elements, see the bottom of this document.
+
+ + + +
@@ -44,7 +53,7 @@ open-source reference implementation for sidechains.
- +
@@ -60,7 +69,7 @@ open-source reference implementation for sidechains.
- +
@@ -110,7 +119,7 @@ open-source reference implementation for sidechains.
- +
@@ -127,7 +136,7 @@ open-source reference implementation for sidechains.
- +
@@ -143,7 +152,7 @@ open-source reference implementation for sidechains.
- +
@@ -159,7 +168,7 @@ open-source reference implementation for sidechains.
- +
From 97ffcf29deae6c430b7f528512e0f668db0e973f Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 2 May 2017 20:03:10 -0700 Subject: [PATCH 22/31] Add @gmaxwell's latest presentation --- source/elements/confidential-transactions/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/elements/confidential-transactions/index.md b/source/elements/confidential-transactions/index.md index 266a068..e585ee0 100644 --- a/source/elements/confidential-transactions/index.md +++ b/source/elements/confidential-transactions/index.md @@ -6,6 +6,8 @@ source: https://github.com/ElementsProject/elementsproject.github.io/blob/master edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/source/elements/confidential-transactions/index.md --- +
+ One of the most powerful new features being explored in Elements is Confidential Transactions. This keeps the amounts transferred visible only to participants in the transaction (and those they designate), while still guaranteeing that no From b609ce13d8f597af9f6c62de6be58d7c9562586b Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 2 May 2017 20:09:01 -0700 Subject: [PATCH 23/31] Add explainer text around video --- source/elements/confidential-transactions/index.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/elements/confidential-transactions/index.md b/source/elements/confidential-transactions/index.md index e585ee0..95cc6d9 100644 --- a/source/elements/confidential-transactions/index.md +++ b/source/elements/confidential-transactions/index.md @@ -6,8 +6,6 @@ source: https://github.com/ElementsProject/elementsproject.github.io/blob/master edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/source/elements/confidential-transactions/index.md --- -
- One of the most powerful new features being explored in Elements is Confidential Transactions. This keeps the amounts transferred visible only to participants in the transaction (and those they designate), while still guaranteeing that no @@ -21,6 +19,12 @@ protection, thieves and scammers can focus their efforts on known high-value targets, competitors can learn business details, and negotiating positions can be undermined. +Watch Blockstream CTO Gregory Maxwell explaining Confidential Transactions at Coinbase: + +
+ +Read on to see how Confidential Transactions can be used, or jump straight to the math. +

Did you know?

By sharing the blinding key used in the construction of a single confidential transaction, users can share access to the transaction's details. Read more about selective disclosure »

From b28ef7939177952e7678d4213557e12d795900c9 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 2 May 2017 21:12:36 -0700 Subject: [PATCH 24/31] Link cleanup --- source/elements/confidential-transactions/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/elements/confidential-transactions/index.md b/source/elements/confidential-transactions/index.md index 95cc6d9..eee10cd 100644 --- a/source/elements/confidential-transactions/index.md +++ b/source/elements/confidential-transactions/index.md @@ -23,7 +23,7 @@ Watch Blockstream CTO Greg
-Read on to see how Confidential Transactions can be used, or
jump straight to the math. +Read on to see how Confidential Transactions can be used, or jump straight to the math.

Did you know?

From ffd945a8a96e0bed51b0dac9ffd4535c71c9e2fe Mon Sep 17 00:00:00 2001 From: James Stanley Date: Thu, 4 May 2017 13:27:01 +0100 Subject: [PATCH 25/31] Remove spurious word --- source/sidechains/creating-your-own.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/sidechains/creating-your-own.md b/source/sidechains/creating-your-own.md index 601f509..c0dd2a9 100644 --- a/source/sidechains/creating-your-own.md +++ b/source/sidechains/creating-your-own.md @@ -4,7 +4,7 @@ edit: https://github.com/ElementsProject/elementsproject.github.io/blob/master/s source: https://github.com/ElementsProject/elementsproject.github.io/edit/master/source/sidechains/creating-your-own.md --- -This is step-by-step guide will walk you through building your own sidechain and +This step-by-step guide will walk you through building your own sidechain and setting up a simple single-signer peg with a `regtest`-powered mainchain. This configuration works to run a sidechain with a 1-of-1 functionary/blocksigner, convenient for local development and testing. From fd101f6801499dde6740742ab2174a68f02d44f4 Mon Sep 17 00:00:00 2001 From: James Stanley Date: Thu, 4 May 2017 13:29:48 +0100 Subject: [PATCH 26/31] Remove spurious word (2) --- source/elements/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/elements/index.md b/source/elements/index.md index c13c434..1030d6d 100644 --- a/source/elements/index.md +++ b/source/elements/index.md @@ -17,7 +17,7 @@ edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/s Elements is an open source collaborative project where we work on a collection of experiments to more rapidly bring technical innovation to Bitcoin. Elements are features that are proposed and developed in this technical community that in arbitrary combinations can be fashioned into sidechains. ## Current Elements -These are the features under currently available in [Elements Core][github], the +These are the features currently available in [Elements Core][github], the open-source reference implementation for sidechains. For projects built with the latest version of Elements, such as [Liquid][liquid], you can expect them to support each of these features. From 9459546a34088ac582c421add1141e64fc2a84f5 Mon Sep 17 00:00:00 2001 From: James Stanley Date: Thu, 4 May 2017 13:43:03 +0100 Subject: [PATCH 27/31] Fix alpha hyperlink --- source/sidechains/alpha/getting-started.md | 1 + 1 file changed, 1 insertion(+) diff --git a/source/sidechains/alpha/getting-started.md b/source/sidechains/alpha/getting-started.md index 90a050c..e3e0697 100644 --- a/source/sidechains/alpha/getting-started.md +++ b/source/sidechains/alpha/getting-started.md @@ -303,5 +303,6 @@ see what you build! [presentation]: https://people.xiph.org/~greg/blockstream.gmaxwell.elements.talk.060815.pdf [elements]: http://elementsproject.github.io +[alpha]: /sidechains/alpha [testnet faucet]: https://testnet-faucet.elementsproject.org/ [elements github]: https://github.com/ElementsProject/elements From 50699772283ea4eff2933bcc40a7e6052ca6d7b9 Mon Sep 17 00:00:00 2001 From: Janus Troelsen Date: Fri, 30 Jun 2017 16:08:44 +0200 Subject: [PATCH 28/31] link andytoshi's Lightning improvements with Schnorr --- source/elements/schnorr-signatures/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/elements/schnorr-signatures/index.md b/source/elements/schnorr-signatures/index.md index 75b4e2c..93b3b7d 100644 --- a/source/elements/schnorr-signatures/index.md +++ b/source/elements/schnorr-signatures/index.md @@ -15,3 +15,5 @@ Potential support for batch validation (up to a factor 2 speedup to verify group Stronger security proof. * Provably no inherent signature malleability, while ECDSA has a known malleability, and lacks a proof that no other forms exist. Note that Witness Segregation already makes signature malleability not result in transaction malleability, however. * Slightly faster to sign/verify than ECDSA. + +Andrew Poelstra lists more advantages on [the MimbleWimble mailing list](https://lists.launchpad.net/mimblewimble/msg00086.html). From 17a8e1398b66d96c5b86cdaa51c6b73fd47733b5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 12 Jul 2017 17:28:39 +0200 Subject: [PATCH 29/31] Fix link to "Federated Peg" blog post --- source/elements/deterministic-pegs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/elements/deterministic-pegs/index.md b/source/elements/deterministic-pegs/index.md index 9498a31..40a52fe 100644 --- a/source/elements/deterministic-pegs/index.md +++ b/source/elements/deterministic-pegs/index.md @@ -12,4 +12,4 @@ Deterministic pegs allow Elements Alpha to carry redeemable testnet coins withou Sidechains, like other alternative chains, can also be secured by merge-mining. However during a bootstrap period of introduction of a new chain, unless the start of merge mining were very well synchronised, there will be a period of lower hashrate. During the early stages of this bootstrap the chain could have low enough hashrate to present a security risk even against a modest powered attacker. Given the challenges of synchronising something as organic and decentralised by design as bitcoin mining, we therefore need a mechanism to bootstrap chain security. We start in this release with a threshold of functionaries and are plan for a later version to phase in merge-mining. -A detailed explanation of the implementation in Elements Alpha can be found in the [blog](/posts/The-Federated-Peg-in-Elements-Alpha/). +A detailed explanation of the implementation in Elements Alpha can be found in the [blog](/posts/the-federated-peg-in-elements-alpha/). From 5882c98aa4e6fce351f277de7d9b5f2d8c370f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Tue, 18 Jul 2017 22:56:18 +0200 Subject: [PATCH 30/31] Update branches (fixes #49) --- source/elements/asset-issuance/index.md | 4 ++-- source/elements/signed-blocks/index.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/elements/asset-issuance/index.md b/source/elements/asset-issuance/index.md index 14998a1..6028064 100644 --- a/source/elements/asset-issuance/index.md +++ b/source/elements/asset-issuance/index.md @@ -2,7 +2,7 @@ title: Asset Issuance description: Create new assets on a sidechain, with optional confidentiality. image: /img/asset-issuance.svg -branch: issuance-final +branch: elements-0.14.1 source: https://github.com/ElementsProject/elementsproject.github.io/blob/master/source/elements/asset-issuance/index.md edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/source/elements/asset-issuance/index.md --- @@ -96,4 +96,4 @@ to pay fees of different asset types simultaneously.

Looking for the original investigation?

Read Jorge Timon's original investigation to learn about the origins of this Element.

-
\ No newline at end of file +
diff --git a/source/elements/signed-blocks/index.md b/source/elements/signed-blocks/index.md index c48a241..4aed712 100644 --- a/source/elements/signed-blocks/index.md +++ b/source/elements/signed-blocks/index.md @@ -2,7 +2,7 @@ title: Signed Blocks description: Blocks can be cryptographically signed, allowing the creator of the block to verify their identity in the future. image: /img/signed-blocks.svg -branch: block-signing-0.10 +branch: elements-0.14.1 source: https://github.com/ElementsProject/elementsproject.github.io/blob/master/source/elements/signed-blocks/index.md edit: https://github.com/ElementsProject/elementsproject.github.io/edit/master/source/elements/signed-blocks/index.md --- From 739f5737401e836cd077363c5b28fef0747db6ad Mon Sep 17 00:00:00 2001 From: Omar Shibli Date: Sat, 16 Dec 2017 23:37:46 +0200 Subject: [PATCH 31/31] the Elements build instructions --- source/sidechains/creating-your-own.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/sidechains/creating-your-own.md b/source/sidechains/creating-your-own.md index c0dd2a9..a352339 100644 --- a/source/sidechains/creating-your-own.md +++ b/source/sidechains/creating-your-own.md @@ -14,7 +14,7 @@ Deterministic Peg Element](/elements/deterministic-peg.html) for more details. #### Prerequisites You'll need a working version of Elements. Follow [the Elements build -instructions](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md) +instructions](https://github.com/ElementsProject/elements/blob/elements-0.14.1/doc/build-unix.md) to get set up. ### Creating your own blockchain