-
Notifications
You must be signed in to change notification settings - Fork 30
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
LSPS6: Unlinkable Service Tokens. #68
Conversation
c854a01
to
a8d22b1
Compare
Updated: add how-to-implement-with-libsecp256k1, add how the challenge string can be Fiat-Shamired. |
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? |
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. |
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. |
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? |
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. |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
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/ |
There was a problem hiding this comment.
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?)
- IETF WG for privacy pass: https://datatracker.ietf.org/wg/privacypass/about/
- Cashu
- 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 |
There was a problem hiding this comment.
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
> 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. |
There was a problem hiding this comment.
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
> 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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* 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.
* `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. |
There was a problem hiding this comment.
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)
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. |
Removing as out-of-scope. |
@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.