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

LSPS6: Unlinkable Service Tokens. #68

Conversation

ZmnSCPxj-jr
Copy link
Contributor

@nothingmuch to check that the roll-my-own-crypto is not obviously broken.

Maybe @TonyGiorgio might be interested in how this might help with separating an LSP-client from the VSS-user.

This is a proposal by which an LSP may issue tokens to its clients for use with other services that the LSP may offer, without linking the client node ID to the token and thus providing client privacy.

@ZmnSCPxj-jr ZmnSCPxj-jr marked this pull request as draft November 23, 2023 01:55
@ZmnSCPxj-jr ZmnSCPxj-jr force-pushed the unlinkable-service-tokens branch from c854a01 to a8d22b1 Compare November 23, 2023 02:35
@ZmnSCPxj-jr
Copy link
Contributor Author

Updated: add how-to-implement-with-libsecp256k1, add how the challenge string can be Fiat-Shamired.

@kingonly
Copy link
Collaborator

Seems out of scope to me. Not sure why this should be an LSP responsibility. Why not keeping the spec focuses only on liquidity services?

@SeverinAlexB
Copy link
Collaborator

I might change my mind in the future but I agree with Roy here. I don't see a reason to add this to the LSPSpec.

@TonyGiorgio
Copy link

I'll have to read the full spec, but I think this is something that can be used specifically for liquidity services. Such as different rates to charge specific users based on services paid for out of band, without needing node pubkey being used as the reference.

@kingonly
Copy link
Collaborator

I'll have to read the full spec, but I think this is something that can be used specifically for liquidity services. Such as different rates to charge specific users based on services paid for out of band, without needing node pubkey being used as the reference.

I don't think so. Any liquidity related service should have a clear interface. We don't need a generalized auth mechanism for that.

@ZmnSCPxj-jr
Copy link
Contributor Author

ZmnSCPxj-jr commented Nov 23, 2023

The use-case is that we want to provide additional services (SPV server, LN state storage, etc.) to our clients, without knowing which client is using the service.

So we want to be able to issue a token to a client to authorize them to use our service. Obviously, to authorize them we need to know that they are indeed our client (e.g. they have a channel with us, or have a promise of a channel via LSPS1 or LSPS2). The unlinkability is to separate authorization from authentication and remove any link "we know this account on our extra service is with this specific client with these channels".

Note that the services are still related to Lightning: e.g. access to an SPV server or access to LN state storage. To be a complete "Lightning SERVICE Provider" we need to add such on-top value-added services as well, not just liquidity.

I mean this IS the Lightning SERVICE Provider Specifications, not the Lightning LIQUIDITY Provider Specifications, is it not? It seems to me that enabling access to additional services, like SPV servers, LN state storage, LN watchtowers would be in-scope, as those are services related to Lightning?

@kingonly
Copy link
Collaborator

It is liquidity service provider. We had this discussion when we started the spec group. Otherwise almost everything can get into the spec (watchtowers, custodial, fiat, etc). This is out of scope imo.

@@ -39,6 +39,9 @@ A channel purchase API to buy channels from an LSP.
### **LSPS2** [JIT Channels](LSPS2/README.md)
Describes how a client can buy channels from an LSP, by paying via a deduction from their incoming payments, creating a channel just-in-time to receive the incoming payment.

### **LSPS6** [Unlinkable Service Tokens](LSPS6/README.md)
Describes how a client can acquire tokens for other Bitcoin- or Lightning-related services from an LSP, while ensuring that the LSP cannot link the client node ID with usage of the service.

Choose a reason for hiding this comment

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

This is a common framing but I find it problematic since users often misunderstand these properties. Unlinkable tokens don't ensure unlinkability of the service: they allow unlinkable authorization which is a necessary but insufficient requirement for unlinkability of the service requests to which they are added.

Ensuring unlinkability at the service request also assumes e.g. an isolated Tor circuit or some other way of obscuring transport level metadata leaks, that request serialization is canonical, that temporal patterns are accounted for, etc.

Given the current state of LSP/VSS stuff such leaks seem unavoidable for the foreseeable future, because while addressing these would be nice on paper, in practice it's basically a ground up redesign with very different considerations for operators, and would require tons of work:

  • reliance on REST where serialization often fingerprints client implementations (ordering & case conventions of HTTP headers, JSON objects, etc).
  • overt links between keys and store_id to allow for enumeration, and versioning

(note that this is independent of the inherent temporal leaks when LSP == VSS)

Using such tokens does, however, still obscure the way that the user has paid for the service, e.g. if a free tier of tokens is trickled out, but they can also be purchased in a variety of ways, that can be unlinked from tokens' redemption, but assuming the client pays over LN even this would be hard to make unlinkable without separating the VSS and LSP role.

tokens, gratis or for a fee, to clients, and how clients can use
the service tokens to gain access to additional services.

This LSPS unlinks two security concepts:

Choose a reason for hiding this comment

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

Suggested change
This LSPS unlinks two security concepts:
This LSPS decouples two security concepts:

(for clarity, avoid the privacy overloaded term "unlink")

stringently derived to achieve Koblitz curve properties; in
theory, NIST could have chosen the supposedly-random parameters
of NIST P-256 / SECP256R1 to have some subtle flaw.)
* The hash function is SHA-256 from the SHA-2 family.

Choose a reason for hiding this comment

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

Mainly posting for completeness, also brought up in other channels, but the STROBE can be used to unify the following building blocks into one underlying primitive:

  • the hash function
  • HMAC
  • PRF

while also providing cryptographically secure (synthetic) nonces, c.f. https://merlin.cool for a concrete approach.

[this sketch](https://asecuritysite.com/encryption/logeq).
* The CSPRNG used in batched DLEQ is ChaCha20.

[PrivacyPass]: https://privacypass.github.io/protocol/

Choose a reason for hiding this comment

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

for completeness, though not sure where this should be linked (maybe an additional "Related Work" section?)

  1. IETF WG for privacy pass: https://datatracker.ietf.org/wg/privacypass/about/
  2. Cashu
  3. Ruben Somesen's post on blind Diffie-Helman tokens

hash, the result can be fed directly into this function to
check if it encodes a point on the curve.
While this becomes a variable-time algorithm, the input to the
hash-to-a-point operation is completely public information and

Choose a reason for hiding this comment

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

nit: t is not a public input, at the time that the client computes it, but it seems to me (an idiot, don't trust me) like a timing side channel could be ruled out based on two

  • the client can do this calculation offline ahead of time, without revealing anything about when it started it
  • each field element is only checked once, there's no repeated use of the same secret inputs

Comment on lines +356 to +360
> Without token expiration, a patient attacker may collect
> tokens over several years, including acquiring tokens from
> hacked or neglected clients (such as by diving into disposed
> storage devices), and then use a large number of tokens to
> overload the LSP-server.

Choose a reason for hiding this comment

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

Also server storage (set of used tokens) has unbounded growth

Comment on lines +362 to +367
> Tokens signed with a particular `S` are linked to that `S`.
> Thus, if the LSP rotate keys too often, it would be able to
> determine if a client acquired the tokens at a particular
> time frame.
> By restricting how often the LSP can rotate keys, such linking
> is reduced.
Copy link

@nothingmuch nothingmuch Nov 23, 2023

Choose a reason for hiding this comment

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

For privacy only allowing redemption of tokens from a single epoch is important, but older epoch might still be honored for conversion to tokens of the latest epoch (or even one that is not yet valid).

To avoid the stockpiling concern, this exchange should not be 1:1 but have some sort of decay, subject to service provider's policy.

them (which would let the LSP link the tokens to specific
clients).
* The LSP-server accepts tokens of the current service key, or
the past N most recent service keys, with N selected by the LSP.

Choose a reason for hiding this comment

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

accepting tokens from past epochs as is is a privacy concern related to the temporal leak, tokens should be converted to the latest epoch when epochs expire before redeeming for a service

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, that seems an important point.

are involved, MUST NOT use a public key that can be
publicly derived from their client node ID) account with the
LSP-server.
* The client needs to show a token before it can access the

Choose a reason for hiding this comment

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

Suggested change
* The client needs to show a token before it can access the
* The client needs to show a token before it can access an

client:account mapping can also be 1:n which seems marginally better for privacy. the server knows n, but this can be set fairly high, clients don't need to use all of their available pseudonymous accounts and don't reveal how many they did use.

Comment on lines +581 to +583
* `too_many_issued` (3) - The LSP-node has already issued valid
gratis tokens to the client, or the length of `blinded_tokens`
is longer than expected.

Choose a reason for hiding this comment

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

maybe it makes sense to distinguish between the temporary and permanent cases, e.g. an issuer can rate limit, maybe with exponential decay, the gratis tokens for a specific client while still allowing clients to obtain new tokens should they lose state and this rate could depend on the current outstanding balance for the token pool as a whole (seems well within operator policy to decide to take the risk)

@nothingmuch
Copy link

I'll have to read the full spec, but I think this is something that can be used specifically for liquidity services. Such as different rates to charge specific users based on services paid for out of band, without needing node pubkey being used as the reference.

I would strongly caution against using this token design for anything that involves floating prices unless that can all be handled at issuance time.

Paying in batches with this kind of token, in order to represent arbitrary values, is problematic as it reveals much more about client states in a way that amplifies temporal side channels, as well as presenting UX friction (creates a dilemma between large & small payments, about how to balance the client's token pool).

I'll hold off on more details until the discussion about scope has been resolved, sorry for the noise with the feedback I already posted.

@ZmnSCPxj-jr
Copy link
Contributor Author

Removing as out-of-scope.

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.

5 participants