Skip to content
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

Clarify one sided payment rules #2837

Merged

Conversation

SWvheerden
Copy link
Collaborator

Description

RFC 201, for tari script, laid out a way to do one-sided payments. This RFC clarifies the calculation of the blinding factor k_b to ensure there is nothing left over to think about by explicitly typing out how to calculate it using Diffie-hellman.

Motivation and Context

How Has This Been Tested?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Feature refactor (No new feature or functional changes, but performance or technical debt improvements)
  • New Tests
  • Documentation

Checklist:

  • I'm merging against the development branch.
  • I ran cargo-fmt --all before pushing.
  • I ran cargo test successfully before submitting my PR.
  • I have squashed my commits into a single commit.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.

sdbondi
sdbondi previously approved these changes Apr 12, 2021
Copy link
Member

@sdbondi sdbondi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

who the sender is so that he can derive the shared secret.

This information can be obtained without needing to communicate with the sender. If the blinding factor \\( k_b \\) was calculated with diffie-hellman using the offset public keypair, (\\( k_{Ob} \\),\\( K_{Ob} \\)) as sender keypair and
the keypair, (\\( k_{Sb} \\),\\( K_{Sb} \\)) as the receiver keypair, the blinding factor \\( k_b \\) can be securely calculated without communication between the 2 parties.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not super necessary, but might be clearer to be 100% specific.
i.e.
The sender calculates k_b = k_Ob * K_Sb, and the receiver calculates k_b = K_Ob * k_Sb

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does the receiver know the value though?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value must be sent out of band.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the value is sent out of band, why not send the whole commitment out of band? Isn't the purpose here to not do out of band?
"This information can be obtained with need to communicate with the sender"

Copy link
Collaborator

@stringhandler stringhandler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to solve the problem of not communicating with the sender

Copy link
Contributor

@hansieodendaal hansieodendaal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarification of the Diffie-Hellman exchange is great.

Discussion:
Maybe we should add a short discussion about how the one-sided payment receiver can expect payments, but not exactly how much it would be, without communicating out of band with the sender. If the value of the payment is not known, the commitment cannot be opened without huge amounts of computing power.

One option is to know who will pay you and to provide them with a short identification string for one-sided payments, for example, an account number, that would be embedded as the proof message in the Bulletproof range proof.

  • Sender(s) knows
    • Receiver public wallet key
    • Tari one-sided payment script variants that would be accepted by the receiver
    • Unique sender proof message, e.g. an account number
  • Receiver knows
    • Sender(s) public rewind key(s)
    • Sender(s) public wallet key(s)
    • Unique sender proof message

The receiver can then scan the blockchain for payments and open the commitments using the following method:

  • Scan all UTXOs for all acceptable payment script hashes; there would only be a few at most, and if the script resolves when inserting the receiver public key, it is for the receiver.
  • With those identified UTXOs, do Bulletproof rewinding with the range of registered sender public rewind keys. If the proof message matches, the rewound value is more than likely the correct value of the commitment.
  • Test opening of the commitment:
    • Use the Diffie-Hellman exchange with corresponding public wallet key to derive the commitment's spending key and the value obtained from Bulletproof rewinding
    • If the commitment can be opened, it comes from the identified sender

@stringhandler
Copy link
Collaborator

@hansieodendaal seems ok, but if the sender rewind keys are public, can't anyone just read all the values? Why not just include the value in metadata? Or maybe encrypt the value and then add it to the metadata?

@hansieodendaal
Copy link
Contributor

hansieodendaal commented Apr 14, 2021

The sender's public rewind key is not common knowledge; it has to be shared out of band, and will only be shared with specific parties. The sender can also at any time change the rewind key or use more than one.

Although additional information can be added as metadata, we get up to 23 bytes worth of data for free that can be embedded in the Bulletproof rewind proof message.

As you suggested, adding the value as encrypted metadata would also be feasible because the opening of the commitment can be tested with the decrypted value and all registered one-sided payment sender public keys. If the correct value was encrypted, the commitment can be opened.

@SWvheerden
Copy link
Collaborator Author

Would using the blinding factor of the utxo or a derived key of that for the rewind key not solve the problem?

@sdbondi
Copy link
Member

sdbondi commented Apr 15, 2021

I'm not very familiar with the RP rewinding maths but would it not be possible to add the value to the range proof using the Diffie-Hellman key k_b or perhaps Hash(k_b) as the rewind blinding key? As part of scanning you would need to derive the DH key for each UTXO and attempt to rewind.

This makes the problem of obtaining the value the same problem as "how do we efficiently/effectively scan for new one-sided payments?".

@sdbondi
Copy link
Member

sdbondi commented Apr 15, 2021

@SWvheerden Beat me to it 😆

@hansieodendaal
Copy link
Contributor

hansieodendaal commented Apr 15, 2021

Would using the blinding factor of the utxo or a derived key of that for the rewind key not solve the problem?

This is a very good idea yes (@SWvheerden and @sdbondi) [using Hash(k_b)], as the sender will not want to share their own private rewind key (pvt_rewind_key). In this way, the sender could still use their own private blinding key (pvt_blinding_key) and keep it secret.
(See Bulletproof rewinding for context)

@SWvheerden SWvheerden closed this Apr 15, 2021
@SWvheerden SWvheerden reopened this Apr 15, 2021
@@ -524,6 +524,10 @@ $$
For Bob's part, when he discovers one-sided payments to himself, he should spend them to new outputs using a traditional
transaction to thwart any potential horizon attacks in the future.

One other problem with one sided communication is the communication of the value of the transaction being sent, and the wallet recovery of one sided payments. We can solve both of these by using (\\( k_{Ob} \\).
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_{Ob}) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We know now have ...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_{Ob}) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_b) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now

@@ -524,6 +524,10 @@ $$
For Bob's part, when he discovers one-sided payments to himself, he should spend them to new outputs using a traditional
transaction to thwart any potential horizon attacks in the future.

One other problem with one sided communication is the communication of the value of the transaction being sent, and the wallet recovery of one sided payments. We can solve both of these by using (\\( k_{Ob} \\).
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_{Ob}) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now
we can encrypt the value (\\( v \\) inside of the bulletproof rewinding, allowing Bob to unlock his payment without revealing any information publicly.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
we can encrypt the value (\\( v \\) inside of the bulletproof rewinding, allowing Bob to unlock his payment without revealing any information publicly.
we use the standard Bulletproof rewinding scheme to encrypt the value (\( v \) inside the Bulletproof range proof,, allowing Bob to unlock his payment without revealing any information publicly. (See [Bulletproof rewinding](https://github.com/dalek-cryptography/bulletproofs/issues/335) for context)).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be "We now use the standard...". Don't need to start a sentence with "And"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a link explaining it in our own repo, not Dalek's?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can always update it later when we have documented it ourselves.

One other problem with one sided communication is the communication of the value of the transaction being sent, and the wallet recovery of one sided payments. We can solve both of these by using (\\( k_{Ob} \\).
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_{Ob}) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now
we can encrypt the value (\\( v \\) inside of the bulletproof rewinding, allowing Bob to unlock his payment without revealing any information publicly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add something like this:


In summary, receiving party scanning the blockchain for one-sided payments therefore involves:

  • Scan all UTXOs trying to unlock the payment script hashes; if the script resolves when inserting the receiver public key, it is for the receiver.
  • With those identified UTXOs, do Bulletproof rewinding with the range of registered sender public rewind keys ((( k_{rewind}G ) as per above). If the proof message matches, the rewound value is more than likely the correct value of the commitment.
  • Test opening of the commitment using the value obtained from rewinding and the spending key from the Diffie-Hellman exchange; if the commitment can be opened, it is intended for the receiver.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't agree with point 2. Point 2 should be rewound using the hash of the blinding factor

Copy link
Contributor

@hansieodendaal hansieodendaal Apr 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

**Edit: ** Strike that We equate the private rewind key to the hash of the blinding factor. Bulletproof rewinding is done with the public rewind key, not the private rewind key.

Please see the explanation below.

@@ -524,6 +524,10 @@ $$
For Bob's part, when he discovers one-sided payments to himself, he should spend them to new outputs using a traditional
transaction to thwart any potential horizon attacks in the future.

One other problem with one sided communication is the communication of the value of the transaction being sent, and the wallet recovery of one sided payments. We can solve both of these by using (\\( k_{Ob} \\).
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_{Ob}) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_{Ob}) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_b) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now

@@ -524,6 +524,10 @@ $$
For Bob's part, when he discovers one-sided payments to himself, he should spend them to new outputs using a traditional
transaction to thwart any potential horizon attacks in the future.

One other problem with one sided communication is the communication of the value of the transaction being sent, and the wallet recovery of one sided payments. We can solve both of these by using (\\( k_{Ob} \\).
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_{Ob}) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now
we can encrypt the value (\\( v \\) inside of the bulletproof rewinding, allowing Bob to unlock his payment without revealing any information publicly.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be "We now use the standard...". Don't need to start a sentence with "And"

One other problem with one sided communication is the communication of the value of the transaction being sent, and the wallet recovery of one sided payments. We can solve both of these by using (\\( k_{Ob} \\).
Because this is a secret key known by Alice and Bob and no one else. We hash this key as a new key, (\\( k_{rewind} = Hash(k_{Ob}) \\). We know have a rewinding secret key for use in bulletproof rewinding. And now
we can encrypt the value (\\( v \\) inside of the bulletproof rewinding, allowing Bob to unlock his payment without revealing any information publicly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't agree with point 2. Point 2 should be rewound using the hash of the blinding factor

@SWvheerden SWvheerden force-pushed the sw_clarify_one_sided_payment branch 2 times, most recently from 02e14cc to 9a8c684 Compare April 20, 2021 09:04
Copy link
Collaborator

@stringhandler stringhandler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this refactor has reverted to some previous errors

@SWvheerden SWvheerden force-pushed the sw_clarify_one_sided_payment branch from 6e17e6b to 5b99577 Compare April 20, 2021 09:32
add explicit formula

Add value encryption

refactor

Update RFC/src/RFC-0201_TariScript.md

Co-authored-by: Mike the Tike <[email protected]>
Update RFC/src/RFC-0201_TariScript.md

Co-authored-by: Mike the Tike <[email protected]>
fix error

update bulletproof to Bulletproof

edit
@SWvheerden SWvheerden force-pushed the sw_clarify_one_sided_payment branch from 16bfe4c to bdf2843 Compare April 20, 2021 11:46
Copy link
Contributor

@hansieodendaal hansieodendaal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@stringhandler stringhandler merged commit 0cc7146 into tari-project:development Apr 26, 2021
stringhandler added a commit that referenced this pull request Apr 28, 2021
Changes since v0.8.8:

Base Node
---
- [#2870](#2870) [base-node] Fixes and tidies up prune mode cleanup
- [#2857](#2857) [base-node] Optimise pruned UTXO sync streaming protocol
- [#2868](#2868) [base-node] Test to reproduce target difficulty problem

Wallet
---
- [#2867](#2867) [wallet] Add option to write unblinded UTXOs to CSV file
- [#2862](#2862) [wallet] Add mined height to display of mined transactions in Console Wallet

Common
---
- [#2876](#2876) [common] Fix incorrect boolean condition
- [#2873](#2873) [tests] Fix case of cucumber
- [#2837](#2837) [docs] Clarify one sided payment
- [#2871](#2871) [tests] Update tests to use sha3
- [#2855](#2855) [tests] Fix re-org test
@stringhandler stringhandler mentioned this pull request Apr 28, 2021
@SWvheerden SWvheerden deleted the sw_clarify_one_sided_payment branch June 30, 2021 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants