It is well known that unconfirmed transactions are not safe because of the risk of double spend. Below is a proposal how to mitigate (not totally eliminate) this risk.
Imagine if the owner of the coin were not able to use his private key more than once, then he wouldn't be able to create another conflicting spend. We cannot take this ability away from him, however we can try to create a strong
incentive (like all of Bitcoin which is built upon incentives)
not to sign a conflicting transaction.
The good news is it is possible.
Bitcoin's ECDSA private keys can be used to sign any number of transactions. If you use the same address to receive coins and pay from this address for multiple purchases, you are already legitimately using the same private key to sign multiple transactions.
There is another class of signature schemes called "one-time signatures", which sounds like exactly what we need. Lamport signature is the most well known example. By nature of Lamport signature, every time you sign something you reveal a part of your private key, and security level of your second signature is half of security of the first signature. You see that despite the name, Lamport and similar signature schemes are not strictly one-time: if you take a Lamport private key with 128-bit security, your second signature will have security level 64 bit which is still moderately secure. Such slow degradation of security is not suitable for our purpose.
My idea is to modify the plain old ECDSA signature scheme and make it one-time. Here is how we can do it.
Standard ECDSA signature depends on a number
k which should be kept private and never reused. ECDSA prescribes that this number should be generated anew for each new signature (randomly or deterministically per RFC 6979). If the same
k is used to sign two distinct messages, the private key will be revealed. It is this nice property of ECDSA that I'm going to make use of:
require that every signer commits to k at the same time that he generates his private key (and bitcoin address). That is, make
k part of private key in the new signature scheme, and the commitment -- part of public key.
Below is full description of one-time ECDSA signature scheme.
Key generation:Generate standard ECDSA private key as usual.
Generate random
k.
oneTimePrivateKey = (
standardPrivateKey,
k)
Standard public key is
x-coordinate of curve point
standardPrivateKey x
G, where
G is generator, x is point multiplication.
Also calculate
r as
x-coordinate of curve point
k x
G (it is exactly the
r from standard signature (
r,
s) ).
oneTimePublicKey = ( standardPublicKey, (
k x
G).x ) = ( standardPublicKey,
r )
oneTimeAddress = base58( hash_and_checksum(
oneTimePublicKey ) )
Signing:Standard ECDSA signature is (
r,
s).
r is already known from the public key. Calculate
s as usual. Since
r is already known from the public key, we can drop it from the signature and keep only
s.
Verification:Reconstruct the standard public key and signature by moving
r from public key to the signature and apply standard ECDSA verification procedure.
The end result is, if the user tries to sign a second unconfirmed transaction with one-time private key described above, he will
have to reuse k, hence disclose his private key. After his private key is disclosed, anyone can take his coins, the miners are, of course, in the best position to do that (they will not honor transactions that send the spilled coins to any address but theirs).
If the first signature is already deep in the blockchain, the second signature is harmless (unless the user had other unspent outputs on the same address).
This one-time signature scheme is most useful for securing unconfirmed transactions as any potential attacker has to consider the risk that the system strikes back and he loses his coins. Then all potential attackers without access to mining resources are probably out of the game.
Obviously, it is not compatible with address reuse. Also, wallet software has to be redesigned to treat creating a second signature on the same key as silly as posting the private key to facebook. If not forbidden in software, users can be tricked to think their transaction didn't come through for some reason, need to send it again ... private key exposed, coins lost.
Since making address reuse impossible in Bitcoin would require major modifications, and also because PoW already solves double spend problem fairly well, I don't see one-time signatures coming to Bitcoin any time soon. However, they may be a good fit for altcoins and sidechains, especially those that already have stealth addresses.
PoS currencies can use one time signatures to address nothing-at-stake issue and make double-voting too risky (double voting is essentially the same as double spending). To sign more than one block, one can derive consecutive private keys in BIP32 style from a master private key and block number.
I made ECDSA signatures one-timed by having signers commit to
k. The same trick can be applied to other signature schemes that involve
k, e.g. DSA, Schnorr.
This idea is not quite new, I searched and found a few publications where it was also mentioned:
https://bitcointalksearch.org/topic/ecdsa-2-of-2-signing-511074http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=057011325AE4FA29DFE5401D31C9AD04?doi=10.1.1.40.2274&rep=rep1&type=pdf