How to do Payment proofs following the original proposal (not the “reverse” one, which has easier payment proofs):
Due to the fact that it is the receiver that finally broadcasts the transaction, the traditional payment proof cannot be performed in this proposal. Here is a proposed solition:
Set up:
- Grin users have a base secp256k1 public key that is used when they receive transactions, call it
B
. Call the associate private keyb
- Grin’s senders of transactions generate an ephemeral secp256k1 key when they send a transaction: call it
S
, and lets
be the associated private key.S
is to be sent by the sender in the slatepack for the receiver to gain knowledge of it to finalize the transaction.
Protocol:
Let’s call c
the Diffie-Hellman secret, which can be computed by the sender and the receiver only:
c = Hash(s.B) = Hash(b.S)
.
Now, the receiver’s partial nonce R_b
could be derived by the following formula:
R_b = c.G + B
. That would work well for building the transaction, but we will modify this a bit in order to enable payment proofs.
Let’s define x = Hash(c||B||tx_amount||timestamp)
. And we actually define R_b
by the following formula instead:
R_b = x.G + B
.
Only the receiver knows the private key of R_b
since only him knows the private key of B
.
Define by R_a
being the sender’s partial nonce, and by R
being the total nonce: R = R_a + R_b
.
R
is going to be onchain data. The receiver, in David’s scheme, cannot trick everyone and use a different partial nonce since the sender has committed to R
when creating his partial signature already.
How can the sender prove payment?
He can do that by doing the three following things:
- Prove knowledge of the secret key to
R_a
- Show that
R - R_a = x.G + B
- Provide the preimage to
x
(and toc
).
The sender has successfully proven that he sent tx_amount
coins at time t = timestamp
to the owner of the public key B
.