ECDSA signatures are computed from a partial hash of the transaction, I'll call it the sighash. One very good reason for this is that the signature needs to be inside the transaction, but isn't known yet. So, at the very least, the place where the signature
will be is replaced with all zeros before computing the sighash. There are opcodes that can change how the sighashes are made. For example, SIGHASH_SINGLE signs the input, and just
one output, but not the rest of the outputs.
When you compute the signature of that hash, you end up with two numbers, a point on the curve specified as (r,s). Turns out that the math that verifies the signature doesn't work
only on (r,s), but it can also work on (r,(-s mod N)) too, and on several other points. This property is known as malleability, and is well known for DSAs. Personally, I had no idea, so I learned something cool today. This isn't a security problem though, since the points are all related, and none of them can be used to reveal the private key, and none of them can be found without knowing the private key.
I'm not entirely sure here, but I think that what Sergio was getting at was that it would be possible to create a transaction that spends an output using the signature (r,s), and a second one that spends the same output with (r,(-s mod N)). You feed one to the network, and then the other goes to your target. Both signatures are valid, so the target sees a legitimate transaction, and the sighashes are the same so the target node won't ask for the network's version of that transaction to compare (because it thinks it already has that transaction).
Remember SIGHASH_SINGLE? You can use it here to sign just the input and the change coming back to your wallet. That is what lets you create two different versions with the same signature. Since only your change is signed, the transaction given to the target has their address in it, but the transaction given to the rest of the world has another address that you control in it. Since they aren't included in the signature, they can be changed at will.
So, why doesn't it work?
Because transactions are identified by the
full hash of the entire transaction, including all signatures, and
not by the sighash. The target transaction signed by (r,(-s mod N)) has a different hash from the (r,s) version, and is therefor a totally different transaction. The target node will see both versions, and since they spend the same txouts, the double spend attempt will be noticed and rejected.
Also note that wallets keep track of things by looking at the contents of transactions, not by recognizing their hashes. If you run the same wallet on two computers, when you spend from one computer, the second will recognize the txout in the transaction and mark it off based on that. (This came up in a
different thread.)
Sergio, let me know if I'm off target here. This is an interesting topic, and I wanted to try to clarify it for the people that have been asking about it. Obviously, I don't want to be putting words in your mouth if you are talking about something different.