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:
- Grin users have a base secp256k1 public key that is used when they receive transactions, call it
B. Call the associate private key
- Grin’s senders of transactions generate an ephemeral secp256k1 key when they send a transaction: call it
S, and let
s 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.
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.
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
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
- Show that
R - R_a = x.G + B
- Provide the preimage to
x (and to
The sender has successfully proven that he sent
tx_amount coins at time t =
timestamp to the owner of the public key