# Eliminating finalize step

**URL:** <https://forum.grin.mw/t/eliminating-finalize-step/7621>\
**Category:** Development and Technical Discussion\
**Created:** [August 2, 2020, 5:10pm UTC](https://forum.grin.mw/t/eliminating-finalize-step/7621 "2020-08-02T17:10:46Z")\
**Posts on this page:** 1\
**Showing post:** 106

<div class="post-metadata">

**Author:** ![oryhp](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.grin.mw/oryhp/32/2923_2.png) [@oryhp](https://forum.grin.mw/u/oryhp)\
**Post date:** [June 27, 2021, 2:13pm UTC](https://forum.grin.mw/t/eliminating-finalize-step/7621/106 "2021-06-27T14:13:38Z")

</div>

I’ve checked a bit the [Eliminate Finalize Step RFC (closed)](https://github.com/mimblewimble/grin-rfcs/pull/59) and tried to achieve similar things, but dumb them down to a simpler model. That’s not to say this is an improvement. I’m merely sharing this because I find it simpler to reason about grin transactions this way. This is mainly because the exchange of data between the parties is symmetric and so is the payment proof.

As any other thing, it may contain flaws.

# Grin partial contracts

This has _nothing_ to do with smart contracts. I just couldn’t think of a better term than ‘partial contract’ and decided to leave it for now. Below I’ll try to explain why I believe it’s not an address - though, if it makes it easier, you can think of them as a version of grin address which contains additional transaction scoped data.

## Notation

Reading some old topics made me realize each one of us uses different variable names (it’s a pain to think about these), so I’ll first explain what variables mean.

We denote `P` as public excess and `p` as its private excess.  
Similarly, we denote `R` as nonce and `r` as its private nonce.

To distinguish public excess and nonce owners, we subscript them by the owner’s first letter e.g.

- `Ps` - Sender’s public excess
- `Rs` - Sender’s nonce
- `Pr` - Receiver’s public excess
- `Rr` - Receiver’s nonce

Schnorr verification equation is defined as the following:

```auto
e*P + R = s*G

```

## Grin partial contracts

Our grin `address` holds ed25519 public key which is party’s identity.  
We define a new construct called grin `partial contract` which along with ed25519 key also holds a one-time pair `(P, R)`. In order to commit to the pair, we also require the contract come with a `signature` for `H(P | R)` with ed25519 key. So a partial contract has the following form

`contract = (ed25519, P, R, signature)`

#### Why not just say that this is a new version of an address?

To avoid confusion. The added triplet `(P, R, signature)` has _nothing_ to do with an address because it’s a _transaction specific_ context. This is why it might be a good idea to keep the identity separated from the transaction context. In other words `partial_contract = address + tx_precommitment`. The way I find it easy to think about it is that each party shows a “partial contract” and then they both commit to the whole.

## Payment proofs

Given two partial contracts

`contracts = (ed25519s, Ps, Rs, signatures)`

`contractr = (ed25519r, Pr, Rr, signaturer)`

We define a payment proof challenge for nonces to be `Rs’ = f * Rs` for the sender and `Rr’ = f * Rr` for the receiver, where

`f = H(H(contracts) | H(contractr) | H(payment_info))` where `payment_info` can be `(amount, memo)`.

Instead of using `Rr, Rs` as nonces in `e`, we use `Rr‘, Rs’`. The idea is to make both parties commit to the payment proof through the challenge `f`. When the sender is signing for Schnorr challenge `e`, they can check that the receiver’s nonce is `f*Rr` and vice versa. This should work regardless whether the flow is SRS or RSR.

The sender can prove they paid to ed25519 public key by showing `(R, contracts, contractr, payment_info)` where `R` is a part of a signature `(R, s)` that landed on the chain. This should be enough to compute `f` and show that `f * contracts.Rs + f * contractr.Rr = R`.

### Soundness of payment proof

We first note that none of the parties reveals the private key of their nonce or excess at any point. I believe our payment proof verification `f * contracts.Rs + f * contractr.Rr = R` can’t be gamed because `f` commits to both contracts and the `payment_info`. This commitment also _commits_ to `R` the signature will use because `R` becomes `R = f * Rs + f * Rr`. Changing the challenge `f` in any way also changes the `R`, so `f` is directly tied to a specific `R`.

_NOTE: It would seem simpler for the receiver to send the signature saying that if `R` lands on the chain, he is considered paid by the sender for some amount and memo. However, this breaks symmetry because in the RSR flow, the receiver is the last one to sign and only learns `R` at the last step. Communicating a signature would require another round of communication. In contrast, the above payment proof happens at step2 for both parties._

## Steps

1. Sender shares their partial contract `contracts`
2. Receiver creates their partial contract `contractr`. Having both partial contracts allows the receiver to compute new challenged nonces Rs’ and Rr‘, the challenge `e = H(M | Ps + Pr | Rs’ + Rr‘)` and produce a partial signature `(Rr’, sr)` which is sent back to the sender along with their partial contract `contractr`.
3. Sender now has both partial contracts, which allows them to computes `e`, verify that the nonces have payment proof challenge `f`, construct their partial signature `(Rs‘, ss)` and produce the final signature `(Rs’ + Rr', ss + sr)` which should be valid for `Ps + Pr` on message `M`.

The only computational difference in RSR flow is that the receiver is the first to share their `contractr`. At step 2, both contracts are known means we have all the variables for the computation.

## Improvements

### Versioning payment proofs

It would likely make sense to add versioning to the payment proof e.g.

`f = H(version | H(contracts) | H(contractr) | H(payment_info))`.

### Payment info simplification

Adding `amount, memo` to the `partial_contract` simplifies things. This would make the whole joint contract independent of external things (except for a document `memo` references which can’t be solved). Embedding the two in the partial contract would mean we’d have two partial contracts:

`contracts = (ed25519s, -amount, memo, Ps, Rs, signatures)`

`contractr = (ed25519r, amount, memo, Pr, Rr, signaturer)`

Note that the sender has `-amount` and the receiver has `amount`. Both could verify that

`contractr.amount - contracts.amount = 0`. This would also simplify the challenge `f` to

`f = H(H(contracts) | H(contractr))`.

The neat part of this representation is that it scales with more parties, we just end up having n partial contracts

`f = H(H(contract1) | … | H(contractn))` and everyone gets to challenge their nonce. Everyone ends up with the same payment proof which proves who sent/received and how much. In this case the payment proof would be `(R, contract1, …, contractn)`.

In a multisignature setting where we have many senders and receivers, it might not be possible to reveal only how much a specific party sent/received. Perhaps we’d need to show all of the partial contracts involved.

---

_[View the full topic](https://forum.grin.mw/t/eliminating-finalize-step/7621)._
