Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: casascius on January 10, 2011, 11:45:31 PM



Title: Second key for Bitcoin wallets
Post by: casascius on January 10, 2011, 11:45:31 PM
I would like to formally propose the idea that the Bitcoin protocol and software be modified to allow the following (or perhaps someone can explain how the following can be done within the existing framework and the transactions still be considered valid):

- Encumber a bitcoin address with a more than one private key (given a signed transaction request by the first key).
- Remove or change the encumbrance (given a signed transaction by all controlling private keys).
- Allow the encumbrance to declare which keys are needed to sign future transactions (e.g. "both keys", or "either key", or perhaps " keyA AND (keyB OR keyC)", where keyA was the original address key).

WHY?

BIG 1. This kind of logic is vital for any scheme that allows Bitcoins to be persisted within tangible objects with embedded private keys, without having to trust that the person who made the object could later steal the bitcoins because he probably knows the private key.  The ability to confidently trade Bitcoins in tangible form is something that would really advance the objectives of Bitcoin within society.

Significant secondary benefits:
2. The possibility of creating trustee-based arrangements that mitigate the risks of: a) theft or loss of wallet.dat b) the failure of a smart card that contained bitcoins
3. All of the benefits that already lead people to open checking accounts that require two signatures

It is my understanding that this might remotely be possible... or at least, that it might be possible within the "operation" syntax used by Bitcoin but may not necessarily constitute a transaction that will be accepted as valid.  Looking for feedback.


Title: Re: Second key for Bitcoin wallets
Post by: casascius on January 11, 2011, 06:30:31 AM
Digging into the source code and trying to understand this scripting scheme, I'm convinced that this is all already possible without modification.  If I understand it right, encumbering bitcoins with two private keys would look like this.

OP_DUP OP_HASH160 key1 OP_EQUALVERIFY OP_CHECKSIG OP_VERIFY OP_DUP OP_HASH160 key2 OP_EQUALVERIFY OP_CHECKSIG

And that "a and (b or c)" logic could be achieved with the "if" conditional operator.

Given the presence of a OP_CHECKMULTISIG, someone has obviously thought of this first.  It's just not visible in the client, but present in the architecture.



Title: Re: Second key for Bitcoin wallets
Post by: theymos on January 11, 2011, 07:27:55 AM
OP_DUP OP_HASH160 key1 OP_EQUALVERIFY OP_CHECKSIG OP_VERIFY OP_DUP OP_HASH160 key2 OP_EQUALVERIFY OP_CHECKSIG

That will work. The keys in your example would actually be key hashes. You can use OP_CHECKSIGVERIFY for the first OP_CHECKSIG to make it a byte smaller.

The scriptSig would look like:
<sig2> <key2> <sig1> <key1>

If you can use full public keys in the scriptPubKey instead of hashes, it becomes even more compact:

scriptSig: <sig2> <sig1>
scriptPubKey: 2 <key1> <key2> 2 OP_CHECKMULTISIG

With OP_CHECKMULTISIG, you can also change the first 2 in the scriptPubKey to a 1 in order to require either key1 or key2 to sign. And you can specify up to 20 public keys with a single OP_CHECKMULTISIG.

Your "keyA AND (keyB OR keyC)" is as simple as this (assuming you can use the full public keys):
1 <keyB> <keyC> 2 OP_CHECKMULTISIGVERIFY <keyA> OP_CHECKSIG

Even when using key hashes, you can use stack ops to manipulate the stack into a format that can work with OP_CHECKMULTISIG, but I don't think that's better in this case. Too bad Script has no loops.

This is all filtered by IsStandard in the current version, but you can probably get new versions to accept it if you create something that uses it.


Title: Re: Second key for Bitcoin wallets
Post by: casascius on January 11, 2011, 03:37:31 PM
OP_DUP OP_HASH160 key1 OP_EQUALVERIFY OP_CHECKSIG OP_VERIFY OP_DUP OP_HASH160 key2 OP_EQUALVERIFY OP_CHECKSIG

That will work. ...
This is all filtered by IsStandard in the current version, but you can probably get new versions to accept it if you create something that uses it.

Judging by the source code, it looks like such a change (update IsStandard) will be very trivial to make when the time comes.