Bitcoin Forum
May 17, 2024, 12:37:50 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Directional & Time-locked Money Storage  (Read 1174 times)
etotheipi (OP)
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
August 21, 2013, 03:06:41 PM
 #1

So I wasn't quite sure what to search for on this topic, so this is probably a repeat.  Please point me to it if it exists already.

Lots of people have asked if there is a way to control the direction of money behind an address/script. Through conventional means, the answer has always been: "No, the network only defines conditions to unlock the money, but can't control what is done with it." If you have the private key(s) for the money to be unlocked, you can do whatever you want with that money.

However, I realized that this is very much possible, through unconventional means. For instance, it's possible to "lock" money until a given time by doing the following.

  • Produce two private keys, with addresses A and B.
  • Send money to address A
  • Create timelocked transaction sending all outputs of A to B
  • Sign it with A
  • Store signed tx in a safe place
  • Destroy private key A

Although I hate the idea of destroying private keys that still have money, this does achieve what was requested (as long as you can be confident that the tx is valid and can be mined). The money is locked with no way to be moved until the locktime expires, and it will only move to address B. There is also no time limit by which it needs to be broadcast, you could keep it in A until you need it, long past the lock time.

The downsides include:
  • (1) If a crazy bug leads to a bad signature or tx, then the money is locked forever
  • (2) Who's going to destroy their private key that has money associated with it?  Users would probably save the private key in some remarkably inconvenient form that would be difficult to recover, but possible if absolutely necessary (encrypt it with a random 50-bit key that will have to be brute-forced, and then bury it in your backyard yard?)
  • (3) If key B is compromised, trying to remove the money becomes a race: as soon as the tx(A->B) hits the network, both you and the attacker are racing to move the new output. You have an advantage though (if you know B was compromised), as you create the signature with A, so you know the OutPoint that needs to be spent by B, and can prepare a subsequent spend and broadcast it 1 microsecond after you broadcast the first tx. But that's by no means any guarantee that yours will be mined, especially if the attacker knows miners who will give him priority (and especially if replace-by-fee is standard)

Above I have only mentioned time-locking money.  I bet if you combine creative scripts and multiple transactions, there's some cool stuff you could do.  But you have to be careful with creating chained transactions, because the malleability of transactions means that you create A-->B and pre-prepare B-->C, but then some jerk on the network mines A-->B after adding an extra padding byte to your signature and the tx hash changes, then your B-->C tx is invalid (because it references A-->B by hash, which is no longer valid).  I know we enforced canonical signatures, but I assume that's not a hard network rule (yet?).

So what else can be done with this?  Is it actually useful?




Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
gmaxwell
Moderator
Legendary
*
expert
Offline Offline

Activity: 4172
Merit: 8421



View Profile WWW
August 21, 2013, 08:10:50 PM
 #2

Yea,  I've suggested exactly that protocol to people too.  One problem is that many cases where you'd want to use it, you also really want to prove to people that you've used it and there is generally no way to provably throw away a key.   One way to solve that is to make the key be a multisig escrow, and then at least you need multiple people to cheat.

But actually. while responding to you I realized that we are SO close to having the possibility of making it provable.

Prior to creating your locking transaction you write your release transaction.  For the input to your release transaction, you make a scriptsig which has the sigtype set to ANYONECANPAY.  You set the signature value to a random number. You hash up the transaction, and then compute the corresponding public key.  Then you send the coins to the corresponding address.

This doesn't work because ANYONECANPAY still binds the input in question.  If the SIGHASH_SINGLE out of range bug were slightly different in its nature then we could make this work using an out of range SINGLE.  But alas.

Even more annoying, it doesn't look like it's possible to add a new SIGHASH type that masks the input txid/vout in a softforking way. Sad

I guess the easiest way to add it to the protocol is a new operation which takes an item off the stack and compares it to the hash of the transaction with all the inputs masked out and rejects if it doesn't match.  This could be soft-fork added and would allow someone to create an output which is only redeemable by a specific transaction.
BrianDeery
Full Member
***
Offline Offline

Activity: 144
Merit: 100


View Profile
August 21, 2013, 10:45:35 PM
 #3

I remember the dinner conversation in San Jose, but I forget the practical problem we were trying to solve. 

This does seem reminiscent of an old lecture I heard imagining an aged benefactor creating a transaction and signing it with a far off nlocktime, then giving the transaction to their grandchildren as inheritance.   After the nlocktime expires, the grandchild would broadcast it to the network and collect the funds.

I agree with gmaxwell, for a single user, I'm not sure that a method like this is has a substantially different net effect compared to a multisignature transaction. 

Current multisignature method : IN-> 2of2 A & B -> SPEND
Proposed method: IN->A + time -> B -> SPEND

To exchange value, the holder would need two things.

1. A secret pre-prepared transaction (A->B)
2. A private key to spend from B for value transfer.
After the lock time, the proposed idea only differs from multisignature by making the first secret a transaction instead of a key.

One benefit I see is if I wanted to allocate an amount only to pay my electric bill, but not pay them quite yet.  An attacker who gets transaction A could only pay my power bill early. This would lock me into spending to the power company, but it would not be transparent to the electric company, since the transaction is private.  The escrow would give visibility to the intended recipient.




I know you guys know this, but for the listening audience: 
One implied benefit this scheme might have is to give a theft victim time to respond to a slow moving attack. They would only know they were attacked when money started moving.  The victim would see value move out of their address A and be able to prepare another transaction to reclaim those funds.   I think that this outcome has two assumptions that are incorrect:

1. nlocktime is not relative time, but absolute time.  it can be either UTC time or block height.  If both secrets were compromised, (the only way this attack would be profitable) the attacker would have the ability to spend funds through B at the same time as the victim. 
2. IF (big if) the chain were forked to allow relative lock time, then it would be a race between the attacker and the victim to get the B->SPEND into the mempool.  The attacker would be prepared and send theirs first.  The victim trying to recover would not have their transaction propagated due to the coins being spend in a previous transaction.  The victim could send their later B->Spend  transaction directly to a miner to get around the relay problem, but the miner would not know who the attacker and who was the victim.  Satoshi nixed the relative time way back when for block chain re-organizational simplicity.




Instead of destroying the first key, I am imagining multiple levels of two factor authentication.   
I am thinking something along the lines of traveler’s checks.  Before traveling, an offline wallet program could pre-authorize a number of transactions from, say, a deterministic wallet.  The preauthorized transactions could be brought traveling, hidden in a TF card immune from pickpocketing (shoe?).  A phone would be the primary spending method, with only one signature needed.  If more value was needed, the presigned transactions could be broadcast to the phone’s address from an insecure internet cafe.  Pre-assigned private keys could also be brought and used to seed a replacement wallet on a replacement phone, also able to be transmitted in an insecure environment.  If both phone and TF card were lost, you could spend the unused balance of the preauthorized transactions once you get back home.  At no point could you be compelled to hand over more than you brought along or the private key/chain code in the deterministic wallet. 
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1083


View Profile
August 22, 2013, 12:19:16 AM
 #4

  • (2) Who's going to destroy their private key that has money associated with it?  Users would probably save the private key in some remarkably inconvenient form that would be difficult to recover, but possible if absolutely necessary (encrypt it with a random 50-bit key that will have to be brute-forced, and then bury it in your backyard yard?)

What is the use case?  Does it require that you provably destroy the info?

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
etotheipi (OP)
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
August 22, 2013, 12:37:34 AM
 #5

  • (2) Who's going to destroy their private key that has money associated with it?  Users would probably save the private key in some remarkably inconvenient form that would be difficult to recover, but possible if absolutely necessary (encrypt it with a random 50-bit key that will have to be brute-forced, and then bury it in your backyard yard?)

What is the use case?  Does it require that you provably destroy the info?

That's part of what this post is asking... is there a use case for it?  I get a lot of people asking this question, but with only a half-baked idea of how they would use it.  I posted because I realized there's a somewhat-satisfactory answer to that question now, but I'm not sure how useful it really is.

There may be use cases for it that don't require proving you destroyed the key.  i.e. if you actually destroyed the private key, then it cannot be compromised, and the money is truly immobile until the locktime, and only to the specified address/script.  

Brian mentioned "inheritance", though locking money for 30 years is potentially similar to destroying it -- part of why you have inheritance is because you don't know when you're going to die, and you want to send whatever is leftover to your next of kin.  But if you time lock all your savings for 30 years, you can't use it yourself in case you live longer than you expected or you need it.  

More likely, someone might use it to force savings behavior.  You prevent yourself from having access to it until a given time.  Or you can give your kid money that they can only unlock when they are 18 years, etc.   Unfortunately, it does not have the benefit you get of an offline wallet, in that you can continue to send money to it afterwards (I know someone would lose money thinking they could...).

Meh.  It may not actually be that useful.  But it also wouldn't surprise me if it might combined with other network features (replacement, non-standard scripts), to do something very creative.

Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
gmaxwell
Moderator
Legendary
*
expert
Offline Offline

Activity: 4172
Merit: 8421



View Profile WWW
August 22, 2013, 01:08:27 AM
 #6

So, when people have asked about this on IRC it was usually because they were confused about what they could accomplish with it.

One use of it is to achieve a time lock safe, e.g. making funds available at some pace to keep a hot wallet filled.  If you construct the locked outputs so they can be alternatively retrieved via a highly secure offline key if there is a detected theft you can move the locked funds away before they unlock.

A subtle implication of timelocking is that if its done conspicuously it reduces the incentives for theft: knowing that at best you'll be racing for the funds, and that it's N months in the future is not likely to be appealing to your typical thief, who don't tend to be long term thinkers.

A more exotic use would be to bond payments to developers of your cryptocurrency itself.  You don't want to pay someone to code a bunch of stuff, have them sell it all ASAP and then later find that their changes were crap and the code insecure making your currency worthless.   So you could pay them funds released at some point in the future.

For the most part, however, things where people think they need locked funds really just want precomputed refunds and don't require actual locking. Precomputed refunds are similar to what you describe, but they don't actually require throwing away any key.
oleganza
Full Member
***
Offline Offline

Activity: 200
Merit: 104


Software design and user experience.


View Profile WWW
August 24, 2013, 11:29:01 AM
Last edit: August 24, 2013, 11:46:35 AM by oleganza
 #7

UPDATE: The idea below won't work because, as gmaxwell pointed out, second transaction must reference first transaction by its hash. And this hash cannot be masked or omitted. But before computing this hash, we need to compute a signature of txB to put in the output script A. And we cannot compute the signature without having a valid hash to A in the first place. Vicious cycle.



So we want to lock some money for some time in the future without even a theoretical possibility to spend it earlier (e.g. by extracting the private keys by torture).

OP_CHECKSIG drops signatures from the script when computing a hash. This is mostly irrelevant today because script never contains signatures in the first place (as since 2010 input and output scripts are not concatenated). But the code is still here and we can use it:

1. Prepare any spending transaction A (single signature, multisig, complex script - whatever).
2. Prepare a valid transaction B with lockTime in 2033 which spends tx A somewhere further.
3. Sign tx B with some random key pair hash type SIGHASH_SINGLE | SIGHASH_ANYONECANPAY. This will be "SigB" and the pubkey will be "PubKeyB".
4. Prepend the output script of transaction A with "SigB PubKeyB OP_CHECKSIGVERIFY".
5. Finally sign tx A and release it.

Now, you don't need to destroy any private keys: you have money provably locked to the transaction B. Even if you release private key that you used, it will not help: the transaction A already requires very specific transaction B to be used and tx B is time-locked.

Note that transaction B input script can be made empty completely, so you don't need to satisfy any extra conditions - just release tx B when it's lockTime is valid.

Why use SIGHASH_ANYONECANPAY and SIGHASH_SINGLE? It will allow you to add extra inputs to tx B if you will need to increase/decrease transaction fees. All other inputs and outputs except the first ones will be zeroed out, so you'll be free to adjust either of them in 20 years as you like.

Thugs will not be able to spend this money today even if they get all private keys from you. This should be enough to make kidnapping and extortion not worth it.

Now you can do something like this: lock 10% of your savings for 1 year, another 10% for 2 years and so on. You'll have steady access to your money if you happen to need it earlier.

Another idea:

Instead of OP_CHECKSIG and one signature you may have 1-of-2 MULTISIG with 2 signatures prepended. And you'll have not just one tx B, but txB1 and txB2. One of them (txB1) will move money further in the future, say, for 1 extra year. And another (txB2) - to your personal wallet. So when some chunk of your savings gets unlocked, you can either spend it (releasing txB2), or simply freeze it for 1 more year by releasing txB1 which will do similar thing as txA did.




Bitcoin analytics: blog.oleganza.com / 1TipsuQ7CSqfQsjA9KU5jarSB1AnrVLLo
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!