Re: [Lightning-dev] Computing Blinding Factors in a PTLC and Trampoline World

2023-07-03 Thread Bastien TEINTURIER
Hey Zman,

I'm a bit confused because you use a different mechanism than the one
specified in the latest schnorr multi-hop locks proposal that I know of,
which can be found in [1].

If we use the construction from [1], it seems straightforward that using
trampoline doesn't have any impact on the protocol: the sender follows
the exact steps of that protocol and sends the left/right locks in the
trampoline onion.

Then intermediate trampoline nodes can draw their blinding factors
randomly, using the exact same steps, but using the right lock they
received as the secret they're trying to learn (from their point of
view, they're simply doing a normal session of this protocol with a
different secret - and don't learn anything about the "real" secret).

If this doesn't seem straightforward, I can create the same kind of
diagram as the one in [1] but for a trampoline scenario to show that
the maths checks out, let me know if that would be useful.

Cheers,
Bastien

[1]
https://github.com/BlockstreamResearch/scriptless-scripts/blob/master/md/multi-hop-locks.md

Le jeu. 29 juin 2023 à 16:49, ZmnSCPxj via Lightning-dev <
lightning-dev@lists.linuxfoundation.org> a écrit :

> Good morning list,
>
> Here is a simple mathematical demonstration of a particular way to compute
> blinding factors such that:
>
> * All non-Trampoline intermediate nodes only need to know one blinding
> factor.
> * The receiver only needs to know one blinding factor.
> * Trampoline nodes can provide the nodes on the sub-routes they decide the
> blinding factors without the non-Trampoline intermediate nodes knowing they
> are on a trampoline and not a "direct" source-to-dest route.
>
> First, let us start with:
>
> * The ultimate receiver has a secret `r`.
> * The ultimate receiver gives the ultimate sender the point `R`, such that
> `R = r * G`.
>
> Now, suppose the ultimate sender is directly channeled with the ultimate
> receiver.
>
> The ultimate sender chooses a fresh random scalar `e`, the "error"
> blinding factor that reaches the ultimate receiver.
> It then constructs an onion with `e` decryptable by the ultimate receiver.
> Together with that onion, the ultimate sender offers a PTLC with the point
> `e * G + R`.
>
> The ultimate receiver can claim that PTLC by revealing `e + r`, as it
> learns `e` from the onion, and knows `r` and the contract is to give `r` in
> exchange for payment.
>
> That is the simplest case.
>
> --
>
> Now let us suppose that the ultimate receiver needs to got through an
> intermediate node, Carol.
> The ultimate sender still needs to choose a final error scalar, `e`, by
> random.
> However, it also needs to generate two scalars, `c` and `d`, such that `c
> + d = e`.
> This can be done by selecting a random `d` and computing `c = e - d` (by
> algebra).
> By algebra, `d = e - c`.
> The ultimate sender then encrypts the onion:
>
> * `e` encrypted to the ultimate receiver.
> * The above ciphertext, and `d` encrypted to intermediate node Carol.
>
> The ultimate sender then sends the PTLC with point `c * G + R` to Carol.
>
> Each intermediate non-Trampoline node --- such as Carol --- then gets the
> input point, adds its per-hop blinding factor times `G`, and uses the
> result as the output point to the next hop.
>
> So Carol receives `c * G + R`.
> Carol then adds `d * G` (which is the `d` error it got from the onion).
> Carol then sends a PTLC (with one less onion hop layer as well) with the
> point `c * G + R + d * G`.
>
> Note that `e = c + d`, so we can re-arrange the PTLC sent by Carol to the
> ultimate sender as `(c + d) * G + R`.
> This is equal to `e * G + R`, the exact same as in the case where the
> ultimate sender is directly channeled with ultimate receiver.
>
> The ultimate receiver therefore cannot know whether it received from
> Carol, or from a further node, as in both the direct case and the indirect
> case, the ultimate receiver sees `e * G + R`.
>
> When the ultimate receiver releases `e + r`, Carol can compute `c + r` by
> taking `e + r - d`, and since `c = e - d`, `e + r - d = e - d + r = c + r`.
> It can then claim the incoming `c * G + R` with scalar `c + r`.
> Carol does not know `c`, it only knows `d`, and thus it cannot compute `r`.
>
> --
>
> Now let us instead suppose that Carol is a Trampoline node, and that the
> ultimate sender does not provide a detailed route from Carol to the next
> Trampoline hop.
> In this next example, the ultimate receiver is actually the final
> Trampoline hop after Carol, but Carol does not know this fact (and should
> not be able to learn this fact).
>
> The ultimate sender learns `R`, then selects a random `e`.
> It then selects `c` and `d` such that `c + d = e`, using the same
> technique as above (i.e. random-pick `d` and compute `c = e - d`).
>
> Now the ultimate sender computes a Trampoline-level onion, with the
> following:
>
> * `e` encrypted to the ultimate receiver.
> * the above ciphertext, `d`, and the next Trampoline hop (i.e. the node ID
> of ulti

Re: [Lightning-dev] Computing Blinding Factors in a PTLC and Trampoline World

2023-07-05 Thread ZmnSCPxj via Lightning-dev
Good morning Bastien,


> Hey Zman,
>
> I'm a bit confused because you use a different mechanism than the one
> specified in the latest schnorr multi-hop locks proposal that I know of,
> which can be found in [1].

It seems to me that my proposal is simply a restatement of the same scheme.

>
> If we use the construction from [1], it seems straightforward that using
> trampoline doesn't have any impact on the protocol: the sender follows
> the exact steps of that protocol and sends the left/right locks in the
> trampoline onion.

I am surprised it needs to send the left and right locks.
I would expect that, since the PTLC arrives at the trampoline node and serves 
as the left lock, the trampoline node would only need to be sent the delta 
scalar between its left and right locks.

My scheme, as stated, allows implementations to internally define a function of 
the following signature:

```Haskell
buildPath :: RandomSource -> GossipMap -> Secp256k1.Point -> Node -> 
Secp256k1.Scalar -> Path
buildPath
  prng -- :: RandomSource
  gossipMap -- :: GossipMap
  finalOrNextTrampolinePaymentPoint -- :: Point
  finalHopOrNextTrampolineHop -- :: Node
  deltaScalar -- :: Scalar
  = undefined
```

The function would use a pathfinding algorithm to generate a raw path (i.e. one 
that is just a set of nodes to pass through) and then for each hop, generate a 
new scalar from the given random source.
Then the function decorates that path with the generated scalars, takes the 
sum, and subtracts that sum from its input `deltaScalar`, to generate the first 
hop scalar that it adds to its input `finalOrNextTrampolinePaymentPoint` (after 
multiplication by `G`) to get the output PTLC point.
It would decorate the last hop with the `deltaScalar`.

For a flat payment function, the payment function can just generate its own 
`deltaScalar` for each attempt (and each part in a multipart attempt) and then 
pass the paths as-is to the onion encoder.

The same `buildPath` can be reused by a trampoline node.
The trampoline node would simply pass in the `deltaScalar` it received from the 
input onion.

Similarly, a payment function through trampoline nodes can reuse the same 
function, as it would simply assign individual deltas to be sent to each 
trampoline node selected by the pathfinding algorithm.
(Or a more basic function can be defined which accepts a set of nodes through 
which to pass a route, those nodes being either direct-hop nodes or trampoline 
nodes)

Regards,
ZmnSCPxj

___
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev