summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Bishop <kanzure@gmail.com>2019-08-07 08:48:06 -0500
committerbitcoindev <bitcoindev@gnusha.org>2019-08-07 13:50:13 +0000
commit459a43cb38425b24e606afe761180987b640c543 (patch)
tree2151c9583d9240f23a831b208c6c82a43b2b0a01
parent2f58b7726aca710d266b7f1f0bb1c58a798f91eb (diff)
downloadpi-bitcoindev-459a43cb38425b24e606afe761180987b640c543.tar.gz
pi-bitcoindev-459a43cb38425b24e606afe761180987b640c543.zip
[bitcoin-dev] Bitcoin vaults with anti-theft recovery/clawback mechanisms
-rw-r--r--18/faab9bf320f157a2d938d0a89e511cf729a297543
1 files changed, 543 insertions, 0 deletions
diff --git a/18/faab9bf320f157a2d938d0a89e511cf729a297 b/18/faab9bf320f157a2d938d0a89e511cf729a297
new file mode 100644
index 000000000..2f58e1e68
--- /dev/null
+++ b/18/faab9bf320f157a2d938d0a89e511cf729a297
@@ -0,0 +1,543 @@
+Return-Path: <kanzure@gmail.com>
+Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org
+ [172.17.192.35])
+ by mail.linuxfoundation.org (Postfix) with ESMTPS id 13A32D4B
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Wed, 7 Aug 2019 13:50:13 +0000 (UTC)
+X-Greylist: whitelisted by SQLgrey-1.7.6
+Received: from mail-vs1-f48.google.com (mail-vs1-f48.google.com
+ [209.85.217.48])
+ by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 272E77D2
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Wed, 7 Aug 2019 13:50:11 +0000 (UTC)
+Received: by mail-vs1-f48.google.com with SMTP id k9so60673936vso.5
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Wed, 07 Aug 2019 06:50:11 -0700 (PDT)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
+ h=mime-version:from:date:message-id:subject:to;
+ bh=Yv885FP/0NT69WBrbIRFQQhVdM5+gbLsjmn2tdPlcgA=;
+ b=gZYYIX4tlLidpDV/E+KnZzoyULaVpfVhDbWiNO+Uk9i3L0FT6NqFJYh83ffZKMN7S5
+ wB8IRcLeOlTtRO5bNMV2ZmDAXzxJ9Fo3TLx25aTvcS0wyNvfRws629IkqnxA2mFi6Wsb
+ Iio3BwFAlJXww8zpq9izSZsez3e0Bz0Fm1/5LuG2qMFBFUbUO2KEnzSdmd0rkEXPu1Yz
+ YzYwvNva1G3z8gUUDw69qwotJRyYs0MDRje+c/gHxqbnhSgs6Zc1/kI6c+C6MxYDeZO2
+ 0gybmsd51tWv475gjvqfy7V4kOwxGPjnsroDbnHkKY2ATIIDL/XxI90hj1CARezbyiXw
+ pqNg==
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=1e100.net; s=20161025;
+ h=x-gm-message-state:mime-version:from:date:message-id:subject:to;
+ bh=Yv885FP/0NT69WBrbIRFQQhVdM5+gbLsjmn2tdPlcgA=;
+ b=kK2q0vi0XtYRO3wLMZDMvnw4Ms5wEo/bh3uj8/mm8n9QntmPCNw9ub7BnqTKWRJqYf
+ lmC4VcDVFgfllYSq8kNCnxkrJH4l8I6/KeNh3kSmgOmAvNqEfG5Rd5z0jBM7Rhe0SGg7
+ x5zmQAxebHynzwx6fDSHiViPDhEPLIkC1qHQ8tP8jm+UfTBYiyIm/rNZVu5C0eHLY2EX
+ Y2OR6YxiupzEIuWMBtOG3Ni89bFFr7VE4tSryih6mr/WTLawD4mkFRGKGMm/InJV68b2
+ 6I5mLZ0AaIEVUH5+SaltSlJ67IVsH6YRQhQY6Ys0Udj3/5a9HhjcO4v8A8mehu92xWXU
+ PiAA==
+X-Gm-Message-State: APjAAAU/+hhRZUqqGdIzMZFA7ZL1Is7xCEVSiiCyXO76wKaCyAYKrkto
+ zuUwZXUF2ZtPi2g0KVN9ph4L9eIx+aPX8RZAwdyDXZJH
+X-Google-Smtp-Source: APXvYqw2F38t/qvkqgYGg8klb2A/991hqLl4bUK8sEGZvJyMCKDHQLR3Qqixp8zX2P/fsP4wlkmSMk+49Lj/O+JFlRs=
+X-Received: by 2002:a67:ee01:: with SMTP id f1mr6134634vsp.3.1565185809617;
+ Wed, 07 Aug 2019 06:50:09 -0700 (PDT)
+MIME-Version: 1.0
+From: Bryan Bishop <kanzure@gmail.com>
+Date: Wed, 7 Aug 2019 08:48:06 -0500
+Message-ID: <CABaSBawe_oF_zoso2RQBX+7OWDoCwC7T2MeKSX9fYRUQaY_xmg@mail.gmail.com>
+To: Bitcoin Dev <bitcoin-dev@lists.linuxfoundation.org>,
+ Bryan Bishop <kanzure@gmail.com>
+Content-Type: text/plain; charset="UTF-8"
+X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,
+ DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM,
+ RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
+ smtp1.linux-foundation.org
+X-Mailman-Approved-At: Wed, 07 Aug 2019 13:52:30 +0000
+Subject: [bitcoin-dev] Bitcoin vaults with anti-theft recovery/clawback
+ mechanisms
+X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
+X-Mailman-Version: 2.1.12
+Precedence: list
+List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
+List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>,
+ <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
+List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
+List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
+List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
+List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>,
+ <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
+X-List-Received-Date: Wed, 07 Aug 2019 13:50:13 -0000
+
+Hi,
+
+I have a proposal for implementing bitcoin vaults in a way that does not
+require any soft-forks or other software upgrades, although it could benefit
+from SIGHASH_NOINPUT which I'll describe later.
+
+I call them pre-signed vaults.
+
+Vault definition
+================
+
+Here, a vault is defined as a transaction setup scheme that binds both the user
+and the attacker to always using a public observation and delay period before a
+weakly-secured hot key is allowed to arbitrarily spend coins. This is the same
+definition previously used[1]. During the delay period, there is an opportunity
+to initiate recovery/clawback which can either trigger deeper cold storage
+parameters or at least reset the delay period to start over again for the same
+keys.
+
+One of the important components of this is the delete-the-key pre-signed
+transaction concept, where only a single transaction is (pre)signed before
+deleting the key. This is basically an emulation of a covenant and enforces a
+certain outcome.
+
+Background and motivation
+=========================
+
+I was looking at Eyal and Sirer's 2016 vaults paper [1], and I saw this
+headscratcher:
+
+> Vault transactions use a delay mechanism. We note that vault transactions
+> cannot be implemented with existing timing mechanisms such as
+> CHECKLOCKTIMEVERIFY opcode or transaction locktime.
+
+This was probably written before the introduction of OP_CHECKSEQUENCEVERIFY.
+Still, a viable construction would have more steps than just using OP_CSV. They
+were probably not thinking about what those steps might be, because in the
+context of the paper they were proposing a bitcoin vault implemented using
+recursive consensus-enforced covenants via a new opcode, which obviously cannot
+be deployed without an upgrade fork. Covenants have been discussed for years,
+but require new opcodes or other consensus-enforcement changes.
+
+Relative locktimes are useful here because there is no knowledge as to when the
+transactions might be broadcasted in the future. The delays need to be relative
+to after the transaction is included in the blockchain, not to setup
+initialization time.
+
+Also, from [2]:
+
+> We show that a [vault transaction] mechanism is currently not possible in all
+> cryptocurrencies [...] Bitcoin's scripting language requires support for
+> covenants.
+
+I haven't seen any previous proposal for how to implement recursive bitcoin
+vaults without a fork and without a covenant. After asking around, I am pretty
+sure this is somewhat novel. The closest I guess is [3].
+
+Vaults are particularly interesting as a bitcoin cold storage security
+mechanism because they enable a publicly observable delay period during which
+time a user could be alerted by a watchtower that a thief might be in the
+process of stealing their coins, and then the user may take some actions to
+place the coins back into the vault before the relative timelock expires. There
+seems to be no way to get this notification or observation period without a
+vault construction. It might have been assumed it required a covenant.
+
+Having a vault construction might go a long way to discourage would-be
+attackers, on principle that the attacker might be incapable of recovering
+their cost-of-attack because the recovery mechanism can lock up the coins
+indefinitely. Griefing or denial-of-service would still be possible, of course,
+but with multisig there might be some ways to put a halt to that as well. I am
+working under the assumption that the attacker knows that the user is a vault
+user.
+
+Vaults
+======
+
+The idea is to have a sequence of pre-generated pre-signed transactions that
+are generated in a certain way. The basic components are a vaulting transaction
+that locks coins into a vault, a delayed-spend transaction which is the only
+way to spend from a vault, and a re-vaulting transaction which can
+recover/clawback coins from the delayed-spend transaction. The security of this
+scheme is enforced by pre-signing transactions and deleting private keys, or
+with the help of SIGHASH_NOINPUT then there's another scheme where private keys
+are provably never known. This enforces that there's only a specific set of
+possible outcomes at every step of the vault.
+
+Some examples of what the set of broadcasted transactions might look like in
+regular usage:
+
+ coins -> VT -> DST -> exit via hot wallet key
+ coins -> VT -> DST -> RVT
+ coins -> VT -> DST -> RVT -> DST -> ...
+ coins -> VT -> ... -> RVT998 -> nuclear abort
+
+where:
+ VT = vault transaction
+ DST = delayed-spend transaction
+ RVT = re-vaulting transaction
+
+The delayed-spending transaction would have a single output with a script like:
+(
+ 30 days AND hot wallet key
+ OR 10 days AND re-vaulting public key
+ OR 1 day AND 4-of-7 multisig
+ OR 0 days and super-secure nuclear abort ragequit key
+)
+
+Another diagram:
+
+ VT_100 -> DST -> (optionally) RVT -> coins are now in VT_99
+ VT_99 -> DST -> (optionally) RVT -> coins are now in VT_98
+ ...
+ VT_1 -> burn-all-coins nuclear abort ragequit (final)
+
+Definitions
+===========
+
+Transactions and components:
+
+* Commitment/funding vault setup transaction. Signed after setting up the
+transaction tree, and it is broadcasted whenever funds are to be placed into
+the vault.
+
+* Delayed-spend transaction. Signed during the vault transaction tree setup,
+and it is broadcasted when the user wants to withdraw coins from cold storage
+or otherwise manipulate the coins. The output script template used by the
+delayed-spend transaction was defined earlier.
+
+* Hot wallet key: Somewhat insecure key. This can also be multisig using
+multiple hot keys.
+
+* Re-vaulting key: It is important to note that the private key either never
+existed (SIGHASH_NOINPUT + P2WPK for the re-vaulting transaction) or the
+private key was deleted after pre-signing the re-vaulting transaction.
+
+* 4-of-7 multisig: This is a group of differently-motivated individuals who are
+responsible for signing transactions. This multisig group is not necessry to
+describe the technique, I just think it's a useful feature for a vault to
+include.
+
+* Nuclear abort key: Also unnecessary. This is a key for which only a single
+signed transaction will ever exist, and that single transaction will spend to a
+proof-of-burn key like 0x00. This key must be extremely secure, and if there
+is any doubt about the ability to keep such a key secured, then it is better to
+not include this in the protocol. Alternatively, maybe include it as an option
+50 layers down in the revaulting sequence.
+
+* Nuclear-abort pre-signed transaction. This is signed during transaction tree
+setup, before constructing the delayed-spend transaction. It is broadcasted
+only if the user wants to provably relinquish coins forever without giving the
+attacker any coins.
+
+* Re-vaulting transaction. This is where the magic happens. The re-vaulting
+transaction is signed during transaction tree setup, before constructing the
+delayed-spend transaction for the parent vault. The re-vaulting transaction is
+broadcasted when someone wants to prevent a coin withdrawal during the public
+observation delay period. The re-vaulting transaction spends the delayed-spend
+transaction outputs. It has a single output with a script created by running
+the entire vault setup function again. Hence, when the re-vaulting transaction
+is confirmed, all of the coins go back into a new identically-configured vault
+instead of being relinquished through the delayed-spend transaction timeout for
+hot wallet key signing.
+
+* Special case: final transaction. This is the very first pre-signed
+transaction during setup, and the transaction spends the coins using any
+provable burn technique. This is broadcasted only at the end of the game, as an
+ultimate abort and forfeiture of coins without giving in to an adversary. It's
+similar to the nuclear-abort ragequit transaction but it sits at the same place
+that a delayed-spend transaction would, at the very end of the rainbow or
+yellow brick road.
+
+Example log during vault setup
+==============================
+
+When running the recursive vault setup function, the created artifacts (in
+order) will look like:
+
+1) choose one of:
+ (first iteration) pre-signed burn-all-coins nuclear abort ragequit (final)
+ (all others) a new vault setup transaction spendable only by its
+ delayed-spend transaction
+
+2) pre-signed re-vaulting transaction sending to vault setup or final
+transaction, with a unique private key
+
+3) pre-signed delayed-spend transaction, with a unique private key
+
+4) vault transaction spendable only by the delayed-spend public key
+
+Pseudocode
+==========
+
+In pseudocode (where PTX is a pre-signed transaction function with
+private key deletion):
+
+ VT(counter, *args, **kwargs) =
+ if counter == 0:
+ DST = PTX("burn-all-coins")
+ else:
+ next_vault = VT(counter-1, *args, **kwargs)
+ revaulting = PTX("only spendable by next_vault public key")
+ DST = PTX("DST policy including revaulting and other conditions")
+ vault = PTX("spendable only by this DST")
+ return vault
+
+Pre-signed transactions
+=======================
+
+What has been known for a while is that a covenant can be somewhat emulated
+using a pre-signed transaction where the user then deletes the private key,
+enforcing that the user's chosen policy must be enforced since there is only
+one existing option and there will only ever be one option.
+
+Such a scheme has been previously described for simple one-time and chained
+vaults [3]. I have learned that the author has an implementation that is in
+preparation, for a non-recursive version.
+
+Note that a series of pre-signed transactions can be considered to be an
+emulation of a covenant. Imagine a linear chain of pre-signed transactions
+where each hop has a relative locktime before being able to broadcast the next
+transaction. To recover the coins at the end of the rainbow, one would need to
+broadcast each sequential transaction in order and wait for the relative
+timelocks to expire each time. Here, covenants provide something like an undo
+for bitcoin, but only between pre-determined addresses and scripts.
+
+Fees for pre-signed transactions
+================================
+
+There's a few different techniques to talk about:
+
+1) SIGHASH_SINGLE|SIGHASH_ANYONECANPAY to let someone add inputs and outputs.
+This can get pretty complex though.
+
+2) Add a zero-value OP_TRUE output and let anyone spend the zero-value output
+and attach a child-pays-for-parent (CPFP) transaction to pay for everything.
+
+3) Pre-sign a variety of different possible fee rates. Unfortunately this
+involves an explosive blow-up in the amount of transaction data to generate. It
+might actually be a reasonable blow-up amount, only resulting in a few hundred
+megabytes of additional data. But given the other options, this is unnecessary.
+
+Delete the key (for pre-signed transactions)
+============================================
+
+The delete-the-key trick is simple. The idea is to pre-sign at least one
+transaction and then delete the private key, thus locking in that course of
+action.
+
+Unfortunately, delete-the-key doesn't really work for multisig scenarios
+because nobody would trust that anyone else in the scheme has actually deleted
+the secret. If they haven't deleted the secret, then they have full unilateral
+control to sign anything in that branch of the transaction tree. The only time
+that delete-the-key might be appropriate would be where the user who deletes
+the key and controls the key during the setup process is also the sole
+beneficiary of the entire setup with the multisig participants.
+
+Alternative fee rates are easier to deal with using delete-the-key, compared to
+a technique where the private key never existed which can only be used to sign
+one fee rate per public key, requiring an entirely new vault subtree for each
+alternative fee rate. With delete-the-key, the alternative fee rates are signed
+with the private key before the private key is deleted.
+
+Multisig gated by ECDSA pubkey recovery for provably-unknown keys
+=================================================================
+
+A group can participate in a multisig scheme with provably-unknown ECDSA keys.
+Instead of deleting the key, the idea is to agree on a blockheight and then
+select the blockhash (or some function of the chosen blockhash like
+H(H(H(blockhash)))) as the signature. Next, the group agrees on a transaction
+and they recover the public key from the signature using ECDSA pubkey recovery.
+A pre-signed transaction is created, which will trigger the start of the public
+observation period described earlier and also start the clock for the bip112
+relative timelock on its output. In the output script, an OR branch
+is added that enables the use of a re-vaulting key which could also be its own
+separate multisig construction.
+
+This is incompatible with P2WPKH because the P2WPKH spending scriptSig needs to
+have the pubkey (to check the hash of the pubkey against the pubkeyhash in the
+scriptPubKey), which in turn makes it incompatible with ECDSA pubkey recovery
+which requires a hash of the message. However, with P2WPK and SIGHASH_NOINPUT
+instead of P2WPKH it could conceivably work. SIGHASH_NOINPUT is required because
+otherwise the input includes a txid which references the public key. With P2WPK,
+the scriptSig only needs a signature and not a public key. Note that what would
+be required is a version of SIGHASH_NOINPUT that does not commit to the public
+key, and I think a few of the NOINPUT proposals are committing to the public
+key.
+
+Alternatively, there may be some constructions using the 2-party ECDSA
+techniques or m-n party ECDSA techniques.
+
+Deploying exceedingly large scripts
+===================================
+
+A brief interlude to share a somewhat obvious construction. I haven't seen this
+written down yet.
+
+Suppose there is a bitcoin script that someone is interested in using, but it
+far exceeds the size limits and sigop limits. To fix this, they would split up
+the script into usable chunks, and then use the delete-the-key mechanism (or
+the other one) to create an OR branch that is signable by a single key for
+which only a single signature is known. That new pre-signed transaction would
+spend to a script that has the output with the remainder of the script of
+interest. Re-vaulting or clawback clauses can be added to that output as well,
+but spending back to the original root script will only work by generating new
+scripts and keys (since the final hash isn't known until the whole tree is
+constructed, it's a dependency loop).
+
+Recursively-enforced multi-party multisig bitcoin vaults
+========================================================
+
+Ideally, to enforce a covenant with impossible fairy dust magic, we would ask
+for a bitcoin transaction that could be self-referential because the
+only-one-signature-ever trick requires that the signed message be known before
+producing the signature, and the signature has to be known before the public
+key can be known, and the public key would have to be included in the
+self-referential message/transaction hash value. So, that's a dependency loop
+and it doesn't work. It would be interesting to explore a variation of this
+idea with masking, such that a value X can be replaced by a hash over the whole
+script with the X value, even though the real script will have the hash.
+Someone else can figure that one out for me :-).
+
+Instead of the self-referential values attempting to reference the same
+script that is in the process of being constructed, an alternative is to use
+the same script template but populate it with different parameters. The script
+template gets reused over and over again, all the way down the tree, until the
+final transaction which could be >100 years into the future once done adding up
+all the relative locktimes. In fact, to create and populate this terrifying
+recursive script tree, the final transaction needs to be created first, and
+then it is given as input to the script template function and that output is
+then given to the script template function itself-- and so on. At each stage,
+there are additional pre-signed transactions and values to remember.
+
+This can be written as:
+
+ final_transaction = TX(spend to 0x0000 to burn the coins)
+ initial_transaction = F(F(...F(final_transaction))
+
+ (This is missing parameters to indicate to the function what the spending
+ keys requirements are to be.)
+
+See earlier explanation for more details.
+
+Each call to the template populating function produces values that each must be
+preserved for a very long time. It is less safe to store all of the pre-signed
+transactions together at the same time, but more convenient. With less
+redundancy, there is an increased chance of losing data over time, which could
+render the coins completely frozen. This doesn't particularly worry me because
+forgetting a key has that property already, and this could be likened to
+hundreds of megabytes of extra key data or something. Unlike the much smaller
+covenant-based (opcode-based covenant) vault construction, the multiple layers
+here can be separately stored and protected, which might be able to protect
+against an adversary that has stolen some of the re-vaulting keys but not all
+of them.
+
+Optimizations can be made to store parameters for generating the remainder of
+the tree, such as using deterministic key derivation, such that megabytes of
+data wouldn't need to be long-term stored. Only the initial parameters would
+need to be stored.
+
+Financial privacy for custody
+=============================
+
+One of the concerns raised in [2] is that if all coins at an exchange are
+stored together in the same vault, then attackers would be able to learn about
+access control policies by observing scripts and keys. Some privacy can be
+recovered by using segregated vaults, at the cost of additional setup
+complexity and keeping more data in long-term storage.
+
+However, note that I think vaults are also useful for personal cold storage
+solutions.
+
+Fail-deadly mechanism
+=====================
+
+An early nuclear abort option can be added to these scripts. This idea was
+explored in [2]. This would be a very cold very secret key that would abort the
+re-vaulting procedure and send all coins to a (provably) nonsense key. This
+allows a vault user to destroy the coins instead of continuously monitoring the
+bitcoin blockchain for the rest of his life. The attacker can't recover their
+cost of attack if they never get the coins, and this eliminates an entire class
+of potential attackers who are directly interested only in financial gain. The
+disadvantage is that if the attacker finds the secret key for the fail-deadly
+mechanism and uses it, then all of the coins are gone forever.
+
+Multisig variations
+===================
+
+The re-vaulting key could be the same key at each layer, or only sometimes the
+same key, or always a unique key stored separately in another secure location.
+
+Additionally, these re-vaulting keys could be subjected to multisig schemes, as
+well as Shamir secret sharing schemes or other secret sharing schemes.
+
+The idea of adding the 4-of-7 multisig component is to avoid griefing
+situations, at the cost of the additional security requirements for the 4-of-7
+multisig group.
+
+Key rotation for vaults
+=======================
+
+Keeping the same hot wallet key for 100 years is not advisable. Rotate the keys
+by setting up a new vault construction and initiating a withdrawal transaction
+from the old vault to the new vault.
+
+Single-use seals
+================
+
+This proposal may have inadvertedly demonstrated a practical way to implement
+Peter Todd's single-use seals concept [4]. I am hesitant to say so, though,
+because I think he would ask for a more sophisticated way to verify seal
+closure.
+
+Paid defection
+==============
+
+It might be advisable to add small rewards for evidence of defection amongst
+multiparty multisig setups. Besides amounts spendable by individual keys from a
+multisig setup, it may be possible to use a zero-knowledge contingent payment
+for a zero-knowledge statement like: I have a signature s over some message m
+which validates for pubkey pk where pk is a member of the multisig group. Then
+the zkcp transaction would pay for knowledge of defectors. The zkcp procedure
+would require interaction with the defector, while the direct pubkey method
+would not. This is similar to companies paying employees to quit when they
+value the payment over the value of continued employment.
+
+Handling change
+===============
+
+It is important to note that this vault setup is one-time and once-only. There
+must only ever be one deposit into one vault. Also, spending some coins would
+require sending the change amount back into a new vault. Alternatively,
+upfront work can be done to set a regular withdrawal stipend or assumption
+about how many coins are left, such that the transaction tree can be
+pre-generated for those possibilities, hence cutting down on future vault
+reinitializations. It would also be possible to commit upfront to only ever
+working in some minimum increment number of bitcoin or something.
+
+It is very important to only fund the vault once, and only with the amount that
+was configured when setting up the vault.
+
+References
+==========
+
+[1] https://fc16.ifca.ai/bitcoin/papers/MES16.pdf
+
+[2] http://www0.cs.ucl.ac.uk/staff/P.McCorry/preventing-cryptocurrency-exchange.pdf
+
+[3] http://web.archive.org/web/20180503151920/https://blog.sldx.com/re-imagining-cold-storage-with-timelocks-1f293bfe421f?gi=da99a4a00f67
+
+[4] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-December/015350.html
+or https://diyhpl.us/wiki/transcripts/building-on-bitcoin/2018/single-use-seals/
+or https://petertodd.org/2016/closed-seal-sets-and-truth-lists-for-privacy
+
+Acknowledgements
+================
+
+* Jeremy Rubin for pointing out something embarrassingly broken in an earlier
+draft.
+
+* Bob McElrath for telling me to use SIGHASH_NOINPUT which I proceeded to
+promptly forget about.
+
+* Andrew Poelstra for the OP_TRUE trick.
+
+* Joe Rayhawk for paid defection.
+
+* Tadge Dryja for pointing out a few differences between SIGHASH_NOINPUT
+proposals.
+
+
+
+Thank you,
+
+- Bryan
+http://heybryan.org/
+