Use of NRD kernels in Grin payment channels

https://lists.launchpad.net/mimblewimble/msg00636.html

4 Likes

My question is not directly related to the link above posted by Tromp, but more related to the rfc that @antioch did on NRD themselves, which is at: https://github.com/mimblewimble/grin-rfcs/blob/master/text/0013-nrd-kernels.md

At some point in time, Antioch specifies that the message of the signature of NRD kernels should be of the form:

Hash(feature | fee | relative_height). (*)

It is specified that users should reuse kernels (duplicate) for new transactions for some mechanism specific to payment channels, and that this duplicate kernel will only be valid after relative_height blocks have been mined since the first occurrence.

Discussion have occurred about enforcing unique kernels for grin, in order to fully avoid replay attacks and as a consequence make grin robust for the long term, as well as resistant to theft.

What about adding a single bit to the message ?
Instead of signing NRD with messages having the form of (*) , we would sign with messages of the form:

Hash(feature | fee | relative_height | switch),

where switch takes the value 0 at the first occurrence of the kernel, and 1 at the second occurrence of the kernel.

That would allow to enforce kernel uniqueness for all kernels and avoid all problems due to replay attacks, including the ones that we may have not figured out.
The scalability cost is negligible since normal kernels take around 100 bytes of data.

If several instances of the NRD kernels need to be produced, switch would take the value i-1 at the i-th instance, and also fixes the problem in that case, so that different kernels would be enforceable including for nrd kernels.

Is there anything that would make preventing us from doing this?

The complication here is we do not necessarily know (in the general case) at transaction creation time if this is the first or second instance of a given kernel on-chain.

This also puts a requirement on all nodes to maintain a full index over all historical kernels to determine the switch value for each kernel to verify the signature.

I dont understand exactly the problem(s).

  1. You are saying in the RFC:
    ”Each node should maintain 2 weeks of kernel history in the local NRD kernel index. This will cover the pathological case of a 1 week rewind and the validation of a 1 week long relative lock beyond that. The primary use case is for revocable payment channel close operations. We believe a 7 day period is more than sufficient for this.”
    So, what is the issue with including switch in the indexation for those two weeks. I understand that relative_height has a maximum of 2 weeks, correct? Pardon my ignorance if it is not the case :slight_smile:

  2. The value of switch is with each NRD kernel, on-chain. it takes 1 bit.

I am quite keen to think and reflect on how exactly we could do a slight modification to ensure that NRD kernels work while not needing to have the same occurrences onchain. The advantage is pretty big. it would allow to provide the guarantee that GRIN is resistant to theft, instead of hoping and praying god that no harm happens through the replays attacks (which will definitely not happen if GRIN starts to have some success).

How do you store the value for i-1 in 1-bit?

As I said in my original message:

”$$If$$ several instances of the NRD kernels need to be produced, switch would take the value i-1 at the i -th instance, and also fixes the problem in that case, so that different kernels would be enforceable including for nrd kernels.”

The If meaning that I do not know. I do not have the knowledge on how payment channels work.

Alright then, it will take more than one bit. You can explain me how many times we allow to have those occurences? can we put a cap? If it is an infinite number of times that we need to allow, then 4 bytes allow you to count all the kernels for the next 100 years at full transaction capacity.
4 bytes is less than 5% of the size of regular kernels

@antioch , I’ll pass the previous trolling.

“The secret associated with the adaptor signature is swapped to allow funds to be claimed while the relative lock locks funds prior to a refund being claimed. We note that NRD kernels and adaptor signatures are not directly compatible as a prior instance of an NRD kernel would have revealed the secret associated with the adaptor signature. That said we can produce transactions with multiple kernels and we can use this to isolate the adaptor signature on a separate kernel alongside an NRD kernel. It is an unresolved question if there is a way to modify the SAS protocol and avoid the need for these additional kernels in Grin/MW.”

What is the problem here that is occurring exactly? Can’t the two same excesses have different signatures? Your proposal doesn’t seem to refer to replays in its description.

Two kernels with same excesses and different signatures do refer to each other.
However, two identical kernels actually don’t refer to each others, due to the possibility of replay.

To be clear, kernels are identical if and only if they share same excesses and signatures.

I’m not sure what this is in reference to?

Two kernels with the same excess can be exchanged for one another, even if the signatures differ.
An adaptor signature would be trivially defeated.

Do you mean here that we don’t commit to kernel’s signature? (I have no idea)

Committing to them would come at no cost basically.

Unlike adding more kernels as it seems you currently propose, which bloats the blockchain.

We commit to theses in the kernel MMR yes. Once a block is on-chain the kernels cannot be modified.
But that does not prevent one kernel from being exchanged for another in a transaction.
A transaction is simply a container of inputs/outputs/kernels (plus an offset).

I dont get what you mean by being “exchanged”. Once a signature is done, its done, and it cannot be re-done unless the two parties agree to redo it.

Both parties agree to build both NRD kernel instances ahead of time.

They cannot use an adaptor signature on both as one needs to be added on-chain (and requires a full signature).
They cannot use an adaptor signature on only_one_ of these instances for reasons described above.

Hence the need for an additional kernel - one for NRD, one for adaptor signature.

Not so clear to me for now.

Does one of the adaptor signatures should not be added on chain?
Is “full signature” a normal signature (by opposition to an adptor signature)?
Which reasons “described above”? I have not understand the “exchange” situation.

If you’re OK we can discuss this more on keybase. I am interested to review more your proposal, but I need a bit of help since I have not worked on this topic during several months like you did. On top of that my proposal to verify kernel uniqueness has the side effect to allow to broadcast transactions ahead of time (arbitrarily) , which might be useful.

1 Like

Does the problem have to do with this:

“We can think of settlement as being done in two equal halves, with 2
equal half-kernels, which is where the NRD kernels come in. In order
to allow for revoking an attempted old settlement, there is a required
delay between 2 instances of the same NRD kernel.”

“say by Alice, she is free to change her blinding factor to any other
while also changing the transaction’s kernel offset by the same
amount, and redoing the rangeproof on her output (she’ll have to keep
Bob’s default output as is)”
https://lists.launchpad.net/mimblewimble/msg00636.html

So is the problem that the kernel is not one one but existing in two parts? Anyhow, hard to grasp for me what exactly the problem is at least I would like to undertand the problem.

Think of an adaptor signature as a full signature with a “piece” missing. This missing piece is the thing that must be revealed to complete the signature.
It is not a full signature and cannot be accepted on-chain.

A good overview of adaptor signatures - scriptless-scripts
Also - https://joinmarket.me/blog/blog/flipping-the-scriptless-script-on-schnorr/

Yes exactly.
Full signature - can be accepted on-chain as part of a kernel.
Adaptor signature - missing a piece, not a valid signature.

So if you have two kernels, one with a full valid signature and one with an adaptor signature then instead of revealing the missing piece, simply use the other signature. Which means you cannot do this safely.

3 Likes

And this would not be safe because of this:

"say by Alice, she is free to change her blinding factor to any other
while also changing the transaction’s kernel offset by the same
amount, and redoing the rangeproof on her output (she’ll have to keep
Bob’s default output as is)”,
So she can change the amoun, or is this not relevant to the issue at hand?

Not directly related.

The adaptor signature here allows a use case of “reveal the secret (the missing piece) in exchange for the funds in the tx”. If the adaptor signature can be trivially bypassed then the secret is worthless.