Eliminating finalize step

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 key b
  • 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.

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:

  1. Prove knowledge of the secret key to R_a
  2. Show that R - R_a = x.G + B
  3. Provide the preimage to x (and to c).

The sender has successfully proven that he sent tx_amount coins at time t = timestamp to the owner of the public key B.

7 Likes