-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] early payment proofs #70
Draft
tromp
wants to merge
13
commits into
mimblewimble:master
Choose a base branch
from
tromp:early-payment-proofs
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 5 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
74e2084
initial version of early payment proofs
tromp 58ed05a
minimize slate size
tromp dafe8ce
fixes and memo size limit set to 32 bytes
tromp 3d42600
motivate use of index and discuss reorgs
tromp 317a8b1
various proof types
tromp b976804
small fixes
tromp e0b8661
add Rs' to witness
tromp 741a17f
fix typos
tromp 9c1f0f6
minor reformatting
tromp 9b2700c
fix typo and ponder alternative pay/sign-to-contract scheme
tromp 74b29ff
retract flawed alternative
tromp cbeea07
possible tiny simplification
tromp 6ecef31
add details for RSR flow with invoice proof type
tromp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
|
||
- Title: early-payment-proofs | ||
- Authors: [John Tromp](mailto:[email protected]) | ||
- Start date: Oct 7, 2020 | ||
- RFC PR: Edit if merged: [mimblewimble/grin-rfcs#0000](https://github.com/mimblewimble/grin-rfcs/pull/0000) | ||
- Tracking issue: [Edit if merged with link to tracking github issue] | ||
--- | ||
|
||
## Summary | ||
[summary]: #summary | ||
|
||
Support generating and validating payment proofs for all transactions, including a timestamp and memo field. | ||
|
||
## Motivation | ||
[motivation]: #motivation | ||
|
||
Payment proofs prevent a payment receiver from claiming they didn't receive payment. | ||
Such dispute/fraud prevention is an essential ingredient to commercial adoption. | ||
|
||
Former payment proofs used in Grin didn't apply to invoice flow, at least not | ||
without additional rounds of communication, which made invoices a difficult proposition. | ||
|
||
They also lacked the ability to specify the time and purpose of payment. | ||
|
||
This RFC changes the transaction building process so that | ||
payees commit to a proof of payment promise before the payer signs for the transaction. | ||
|
||
## Community-level explanation | ||
[community-level-explanation]: #community-level-explanation | ||
|
||
A payment receiver, in their earliest round of communication to a payment sender, | ||
shall provide a signature that makes the following promise: | ||
appearance of certain on-chain data satisfying certain conditions | ||
shall prove payment for a specified purpose. | ||
|
||
This early provision of a payment proof promise enables its use in all possible transaction building flows. | ||
|
||
The first byte of signed data will be used as payment proof type or version (similar to how we encode kernel features). | ||
|
||
## Reference-level explanation | ||
[reference-level-explanation]: #reference-level-explanation | ||
|
||
### Payment Proof is a Witnessed Promise | ||
|
||
Since the receiver signature is a promise that payment is proven by | ||
certain on-chain data satisfying certain conditions, we shall call such data a witness, | ||
and let a payment proof consist of a promise paired with a witness. | ||
|
||
### Slate changes | ||
|
||
To accomodate the various proof types, the slate will include the following related fields: | ||
|
||
* `receiver_address` - An ed25519 public key for the receiver, typically the public key of the user's v3 onion address. | ||
* `timestamp` - The time at which the receiver generates the payment proof | ||
* `memo` - A string of size at most 32 bytes that may contain additional payment details, | ||
or the hash of an arbitrary invoice document | ||
* `promise_signature` - A signature that validates against the `receiver_address` | ||
over a promise message consisting of 1 byte of proof type, followed by type specific data | ||
|
||
Note that although the sender address is commonly among the signed data, it need not be included in the slate, | ||
as both sender and receiver necessarily know it. Slates should only contain the absolute minimum of information | ||
that needs to be relayed to the other party. | ||
|
||
### Proof type Legacy | ||
|
||
These follow the original Payment Proofs RFC in the references. | ||
The signature is over | ||
- proof type `0x00` | ||
- `amount` | ||
- `kernel_commitment` | ||
- `sender_address` | ||
|
||
The witness is an on-chain kernel with the given commitment. | ||
The proof type is actually the most significant byte of the amount field, | ||
which is necessarily 0 in the foreseeable future. | ||
The amount field is therefore limited to 7 bytes. | ||
|
||
### Proof type Invoice | ||
|
||
This will be the type for regular invoices, where receiver specifies the time, amount and purpose of payment. | ||
The signature is over | ||
- proof type `0x01` | ||
- `amount` | ||
- receiver public nonce | ||
- receiver public excess | ||
- `sender_address` | ||
- `timestamp` | ||
- `memo` | ||
|
||
For consistency with the old proof type, the amount is again limited to 7 bytes. | ||
The witness is a triple (s,i,C) where i is the MMR index of an on-chain kernel K with commitment C, | ||
satisfying s\*G = R + e\*X, where R is the receiver public nonce, X is the receiver public excess, | ||
and e is the hash challenge of kernel K. | ||
The reason for including the kernel index is that nodes don't maintain | ||
an index of all kernels, and looking for the index of a potentially very old kernel is rather expensive, | ||
and proof verification should not be a DoS vector. | ||
The reason for including the kernel commitment is so that the prover can recompute the index | ||
when necessitated by chain reorgs. | ||
|
||
### Proof type SenderNonce | ||
|
||
This will be the type for indeterminate invoices, where sender commits by nonce to the time, amount and purpose of payment. | ||
This roughly follows the payment proofs in David Burkett's Eliminate Finalize Step RFC (see References). | ||
|
||
The signature is over | ||
- proof type `0x02` | ||
- 7 zero bytes | ||
- receiver public nonce | ||
- receiver public excess | ||
- `sender_address` | ||
|
||
The witness is a triple (s,i,C,m) where i is the MMR index of an on-chain kernel K with commitment C, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo, quadruple not triple |
||
satisfying s\*G = R + e\*X, where R is the receiver public nonce, X is the receiver public excess, | ||
and e is the hash challenge of kernel K. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the "and e is the hash..." is repeated twice. |
||
Additionally, the sender nonce Rs, computed as the difference between kernel nonce and receiver public nonce, | ||
must be of the form Rs' + H(Rs' | m) \* G, where message m contains the promise fields | ||
- proof type `0x02` | ||
- `amount` | ||
- `timestamp` | ||
- `memo` | ||
|
||
### Wallet actions | ||
|
||
#### receiver excess generation | ||
|
||
The `receiver_signature` is generated and added to the slate as part of the receive tx-building step. | ||
|
||
#### sender partial signing | ||
|
||
Before signing, the sender verifies the receiver signature and checks the payment details. | ||
|
||
## Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
* Addition of timestamp and memo increase the size of tx slates. | ||
|
||
## Rationale and alternatives | ||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
## Prior art | ||
[prior-art]: #prior-art | ||
|
||
* Wallet713 implements payment proofs for grinbox transactions, which our design adapts and builds on to work more seemlessly with onion addresses and with transaction building methods that don't inherently rely on addresses. | ||
|
||
## Unresolved questions | ||
[unresolved-questions]: #unresolved-questions | ||
|
||
## Future possibilities | ||
[future-possibilities]: #future-possibilities | ||
|
||
## References | ||
[references]: #references | ||
|
||
* [Payment Proofs RFC](https://github.com/mimblewimble/grin-rfcs/blob/master/text/0006-payment-proofs.md) | ||
* Beam's payment proof model: https://github.com/BeamMW/beam/blob/c9beb0eae55fa6b7fb3084ebe9b5db2850cf83b9/wallet/wallet_db.cpp#L3231-L3236 | ||
* [Eliminate Finalize Step RFC](https://github.com/DavidBurkett/grin-rfcs/blob/eliminate_finalize/text/0000-eliminate-finalize.md) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the intent here to have this field arbitrarily sized (which has implications for binary serialization, which we support)? It might be more clear to define this as 'an optional 32 bytes of data that may contain, serialized in string-hex representation'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think for definiteness we should allow any memo up to say 1KB, and make this field the mandatory memohash (blake2b of memo).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, that makes sense and covers future possibilities a bit better. I'll draw your attention to the Slate V5 PR once it's ready for review, and we can revise this RFC based on that