Eliminating finalize step

I want to describe another attack on the scheme, which is fixable with a slight modification of the protocol.

EDIT: As tromp points out below, I did a mistake in this attack and the below is not correct.

The attack:

Party A does a first legit transaction to party B. s_A: partial signature of the sender, s_B: partial signature of the receiver.
s_B = x + b + Hash(m).x_B.
with x = Hash(R_a, B, amount, timestamp).
Total nonce R is R = R_a + B + x.G.
Then, s = s_A + s_B is a valid signature on total excess X for total nonce R. Up to here, everything is fine.

But later Party A can replay the transaction without the participation of party B with using a different x (call it x’) on a different partial nonce R’_a:
R’_a = R_a - x’.G + x.G.
x’ = Hash(R’_a, B, amount’, timestamp’),

s = s_A + s_B is in fact a valid signature on excess X for total nonce R’ = R’_a + (B + x’.G).
But one can notice that R’ = R, which means the message of the first signature can be replayed with using R’_a as sender’s address and x’ as the “payment proof part” of the receiver’s nonce.

Use amount’ = $1,000,000 in x’ and party A is able to prove that he paid $1,000,000 to party B without party B participating.

In initial proposal, we had:
R_b = x.G + B.

Fix: replace by
R_b = x.G + x.B.

That way, party A would have to use an adjusted nonce R’_a for the second transaction equal to:
R’_a = R_a - x’.G + x.G - x’.b + x.b
But he would not know the private key of this R’_a because he does not the value of b.

Hence party A will not be able to provide correct payment proof for the second transaction as a correct payment proof requires a proof of knowledge of the private key to sender’s nonce.

Of course the fix is only necessary if solution 1. (put burden on user and wallet devs) is chosen. If nonce uniqueness at consensus level is chosen one can keep R_b = x.G + B since the attack relies on using the same total nonce.

2 Likes