mimblewimble / grin-wallet

Grin Wallet
Apache License 2.0
183 stars 133 forks source link

Non-interactive transactions seem lower-friction than interactive ones #77

Closed Arvanaghi closed 5 years ago

Arvanaghi commented 5 years ago

Is your feature request related to a problem? Please describe. Non-interactive transactions (e.g. Alice -> Bob) seem both plausible and lower-friction than the current Alice -> Bob -> Alice workflow.

Describe the solution you'd like Alice wants to send to Bob, so instead of getting commitments from Bob, she creates her change output for herself and also picks all the private values Bob would have picked for his output. She completes the transaction.

Then, at some point in the future, Alice sends Bob all the secrets she chose for him, along with the output. Bob runs:

grin take-ownership <File containing the secrets Alice chose for Bob> ...which automatically creates a Grin transaction from the output Alice made for Bob to a new output that only Bob controls.

So two total transactions, but one less interaction needed between Alice and Bob. And, these two transactions would automatically condense on-chain, because they model an Alice -> Bob -> Charlie chain.

Describe alternatives you've considered N/A

Additional context The trust relationship in the existing Grin transaction model is exactly the same as in the one I am proposing. In my view, this proposal is strictly an optimization. Let's examine.

In my proposal, the risks are: 1) Bob can try and take-ownership of the transaction, and see that the transaction has already been spent. 2) Bob can try and take-ownership of the transaction, and see that the amount is not what he had hoped. 3) Bob can try and take-ownership of the transaction, successfully collect the Grin, and claim he never received it.

All of these risks are present in the existing Alice -> Bob -> Alice interactive model. Why? Because everything relies on Alice anyway.

After receiving Bob's partial signature, Alice is the one who needs add her signature, and then broadcast the transaction. Bob can't!

Knowing this, the risks of the existing model are: 1) Alice could never broadcast the transaction. At best, Bob can say "you didn't send me Grin!" and Alice could say "yes I did!". In a dispute like this, there is literally no way that Alice could prove she sent the Grin to Bob. --> Similarly, in my proposal, Bob could say "the blinding factor and output you sent me -- you already spent it!" and Alice could say "no I didn't!" 2) Bob could successfully receive the Grin, yet still tell Alice "you didn't send that Grin to me -- you sent it to someone else/a blinding factor you control!" --> The same risk is present in my proposal.

GandalfThePink commented 5 years ago

First, it seems simpler to realise this as a 1-of-2 multisig, which avoids sending critical private keys.

But the main problem with this approach is that it creates twice the chain data as a current transaction. And the first transaction is not really achieving much, as it is just Alice paying herself and promising it to Bob. In order to finalise Bob still needs to claim, as soon as possible to have final confirmation.

I have not looked at this, but is seems more promising to think about a new way of communicating slates instead pushing the intermediate state on the chain. Potentially there is a way that Alice can just send a precommited slate to Bob, and Bob can finalise the payment later, given that Alice has the funds in question. This would make this idea much more appealing.

Apart from that I have written a lot on offline transaction in a much more technical sense in https://github.com/mimblewimble/grin/issues/2504, but that requires BLS signatures plus a change in the consensus rules. However, this would enable true offline transactions.

GandalfThePink commented 5 years ago

I guess Alice could send a finalised 1-of-2 multisig slate to Bob (but not to the chain). Bob can then spent that output to his wallet and immediately create a cut-through so the chain only sees the direct Alice-> Bob?

antiochp commented 5 years ago

I guess Alice could send a finalised 1-of-2 multisig slate to Bob (but not to the chain). Bob can then spent that output to his wallet and immediately create a cut-through so the chain only sees the direct Alice-> Bob?

I think so yes. We've discussed ideas similar to this in the past - a "smart enough" wallet would be able to encapsulate all this internal detail and produce a final cut-through tx that looked like a regular tx (with one additional kernel from the cut-through).

GandalfThePink commented 5 years ago

That seems like a good feature to implement. The slate could be communicated over any medium, one could send coins by email, sms, whatever. Of course receiver should still claim at the earliest convenience as Alice might at any moment spent the committed output.

antiochp commented 5 years ago

Alice could never broadcast the transaction. At best, Bob can say "you didn't send me Grin!" and Alice could say "yes I did!". In a dispute like this, there is literally no way that Alice could prove she sent the Grin to Bob.

That's not entirely true. During the initial Alice -> Bob interaction Bob can inspect the chain and confirm for themselves the outputs being spent are indeed unspent and with sufficient # confirmations to be confident they will unlikely to be double spent. Bob knows the inputs and the proposed outputs at this point.

If Alice then fails to complete the tx then Bob can observe this on chain. If Alice decides to spend her output elsewhere, Bob can also observe that.

From Bob's perspective the tx is only "legit" when they see the new outputs and the kernel(s) on-chain.

From Alice's perspective sending a private key to Bob is incredibly risky. There is nothing to stop Malory from taking possession of it (Bob could just email it to them). Alice loses the money regardless of who claims it, while Bob gets to claim they never received it.

What you are proposing is analogous to simply emailing somebody a Bitcoin private key.

Arvanaghi commented 5 years ago

During the initial Alice -> Bob interaction Bob can inspect the chain and confirm for themselves the outputs being spent are indeed unspent and with sufficient # confirmations to be confident they will unlikely to be double spent. Bob knows the inputs and the proposed outputs at this point.

If Alice then fails to complete the tx then Bob can observe this on chain. If Alice decides to spend her output elsewhere, Bob can also observe that.

Am I correct in stating that no matter how we slice things, Bob is at Alice's whim? Either by her spending the output herself, by sending it to someone else, or by never spending it, Alice always has plausible deniability.

I sent this to @lehnberg last night:

I think the biggest downside to this is that in the interactive model, if Alice wants to send to Bob, and there's a malicious person Mallory involved, Mallory would have to trick Alice twice into thinking she is really Bob (once in receiving the tx file from Alice, once in Alice receiving Mallory's response file)

In my scenario, there's only one instance of "being tricked", because whoever receives that private file controls it.

There is an added element of a "secret" in what I described, which I agree adds some more security concerns. But, if you are already being man-in-the-middle'd, then this "secret" has no additional security concerns.

This "secret" portion can be easily solved, though, by encrypting the file with Bob's known GPG key.

Arvanaghi commented 5 years ago

As @GandalfThePink mentioned, cut-through could be done instantly by Bob in his 1 of 2 multisig approach, which is nice.

mcdallas commented 5 years ago

I don't like this at all. Why do we use public key cryptography at all if we are sending around private keys? That should never ever be the case.

Let me remind you that we use bip32 HD wallets WITHOUT a hardened derivation path and leaking a single private key can lead to the whole chain being compromised.

From BIP32:

One weakness that may not be immediately obvious, is that knowledge of a parent extended public key plus any non-hardened private key descending from it is equivalent to knowing the parent extended private key (and thus every private and public key descending from it). This means that extended public keys must be treated more carefully than regular public keys. It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of account-specific (or below) private key never risks compromising the master or other accounts.

ignopeverell commented 5 years ago

I agree with @mcdallas, passing around private keys is a no for a variety of reasons, including key derivation or the hazards of taking keys that may have been chosen in a very particular way by an attacker. The problem isn't only in the transmission, but also with Bob having one of Alice's private key. Even with hardened keys, it adds security assumptions we haven't needed so far.

I also don't see a 1-of-2 scheme that wouldn't be interactive right now? And I do agree that if we can address the problems in #2504, it sounds like a more promising direction overall.

Arvanaghi commented 5 years ago

The "knowing one blinding factor means you can know all of them" piece was new information to me.

I don't think there's anything inherently wrong with sharing a single-use private key. This is not uncommon in different protocols.

I think there is value in adoption for non-interactive transactions (single-direction data flows). But, this seems like a good place to close this discussion. Thanks everyone for discussing.

GandalfThePink commented 5 years ago

The problem with sharing private keys is that it puts the security into the users hand. But the solution should be secure by default. Of course there is always room for user error, but we can try to minimise that. And the best way to do that is to use one shared cryptographic standard and not add another layer of differently encrypted communication on top.

Right now a transaction is a triple interaction sender->receiver->sender and this allows a single signed kernel. We can send slates offchain and add any time-delay we want between these steps. But that alone does not make a convincing offline payment because the receiver needs to find confirmation from the sender at the end and is not in full control over funds until the end.

But if we change the protocol to sender->receiver, that already improves it a lot. Because the reciever does not have confirmation until they pushed to the chain, but they can spent the output at any moment without having to wait for the sender.

I think we can have such a sender->receiver protocol at the cost of one extra kernel. In essence the last interaction of the sender is just to aggregate the kernels. To do this Alice signs of a transaction to either a shared secret or blinding factor of 0. She can finalise this transaction on her own. Instead of putting it on chain she sends the slate to Bob, that now could send it to the chain.

Instead Bob builds his own transaction from the (at this moment) fictional output to his address. Again he can build this transaction on his own. But instead of putting the two transactions to the chain independently Bob immediately cuts through the intermediate state and publishes this along the two signed kernels.

Alternatively the wallet could see if Alice is online and try to get her to aggregate the kernel to minimise transaction costs.

Now we have unconfirmed but offline and offchain payments at a rather low additional cost in chain-weight.

Possibly I am missing some crucial point here why this cannot work or is not secure. But so far this seems to work and could be a simple and convenient payment protocol.

antiochp commented 5 years ago

To do this Alice signs of a transaction to either a shared secret or blinding factor of 0.

I think this works but we now have either -

GandalfThePink commented 5 years ago

@antiochp Yes exactly.

The anyone can spend is risky if you do not share the slates securely. But at least you are not sharing secret keys. The shared secret is obviously better but needs some extra setup, which is not at all trivial to implement.

Arvanaghi commented 5 years ago

Reopening, as there is still discussion taking place.

yeastplume commented 5 years ago

Closing, as I don't think any particular actions will come from this issue. (Always open to further specific proposals, of course)