I would like to make a serious visit to a proposal I made in some other thread a while back, and that's to propose a modification to OP_CHECKSIG.
First, let me describe the very specific benefits that could be gained from implementing the proposal.
- Users could generate a Bitcoin address that, upon receipt of bitcoins, are automatically encumbered by 2 private keys, or a 2-of-3 key strategy - directly lessening people's risk of getting their coins lost or stolen.
- New Bitcoin addresses could be generated securely in halves by two different machines, where neither machine (nor someone who has rooted it) has enough private key material to spend the funds.
- All Bitcoin addresses generated in the above two schemes would be fully backward compatible and well-formed and nobody would need to modify their interactions with bitcoind to accommodate outgoing payments to these addresses
And let me describe how all of these wonderful benefits could be achieved.
- One simple change to the OP_CHECKSIG command.
- Yes, this would require a fork of the block chain, but this doesn't have to be done now, soon, or ever, just for this purpose alone.
- Just put the code in now and leave it disabled thru block 250000 on the production chain until some other external cause forces us to fork the block chain for some other reason. By then, the current versions will definitely be extinct dinosaurs, and if a block chain fork were ever to happen sooner, the block number could be conveniently moved, just how namecoin's merged mining went from 25000 to 19200 when the occasion presented itself.
And now let me describe what the change is.
- Change the OP_CHECKSIG command, so where it now takes ONE pubkey and ONE signature, it would optionally take a binary-serialized boolean expression of n pubkeys in place of the one pubkey, and n signatures to sign against the pubkeys, some of which may or may not be present in any given transaction.
- Right now, a bitcoin address encodes a hash of a pubkey. With this addition, a bitcoin address could encode the hash of the entire binary serialized expression. (The OP_HASH160 would still work exactly as it did before, it would just be hashing more bytes).
- To spend the funds, the spender would need to provide the entire expression in place of the pubkey. The entire expression would still be a single blob of bytes on the scripting stack just like a pubkey, but would just be a little larger
So here is an example. The way it works now, I send bitcoins to address X. My client emits:
OP_DUP OP_HASH160 hashofpubkeyofX OP_EQUALVERIFY OP_CHECKSIG
And when X goes to spend them, he emits a scriptsig of:
signatureforX pubkeyofX
With this modification, address X could be based on the hash of a little script that actually contains three pubkeys arranged in the form (A AND B) OR C. Since a bitcoin address represents a hash, and a hash is taken on a blob of bytes, nothing says that the blob of bytes couldn't be a script rather than a single public key. A client would still emit the exact same script:
OP_DUP OP_HASH160 hashofpubkeyofthewholescript OP_EQUALVERIFY OP_CHECKSIG
And if X wanted to spend them, and he has private keys for A and B, he would emit:
signatureforA+signatureforB+null script:(pubkeyforA AND pubkeyforB) OR pubkeyforC
The OP_CHECKSIG would pass because the script can be satisfied with just the two of three signatures.
And if X wanted to spend them and he only has has private key for C, he would emit:
null+null+signatureforC script:(pubkeyforA AND pubkeyforB) or pubkeyforC
Now, how secure bitcoin address generation would work:
Joe wants a secure bitcoin address, but is rightly afraid of viruses and keyloggers. He need not fear, since he will use two virus-infested devices to securely generate an address.
He generates one ECDSA keypair on his virus-infested PC with a keylogger and remote viewing trojan monitored by someone in Romania.
He generates a second ECDSA keypair on his Blackberry that has been rooted by his wireless carrier at the behest of his government, via an online website that secretly keeps a copy of all the private keys it produces.
He writes down both private keys.
With either of these computers, he creates a single Bitcoin address by hashing his two public keys together. Unless he uses two machines both pwned by the same attacker, or the two attackers have some way to find one another and do a "show you mine if you show me yours", he is pretty much safe from attacks because neither of his adversaries knows the other private key and both are needed to spend the funds. Heaven forbid he generate one of these keys using a device that has no internet connection, and there's no way he'll be able to get his bitcoins stolen.