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

Max/zknym doc tweak #5223

Merged
merged 2 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ However, the offline approach introduces certain limitations.
- Any potential repercussions against double spenders can only be implemented once the user requests a new credential for their zk-nym Generator (aka they have to 'top up' and buy more bandwidth allowance), assuming they haven't altered their identifier (the Bech32 address).

An exploitable scenario arises from these limitations:
- A malicious user purchases bandwidth and aggregates a valid zk-nym credential in the standard way, worth $10 of crypto/fiat. Subsequently, the malicious user proceeds to sell the credential to 100 users for $1 each, allowing each user to generate zk-nym credits of 100MB from this **valid** credential. Under the offline approach, entry nodes forego double-spending checks; so long as the clients all used different ingress Gateways, all 100 users could access the network without obtaining a subscription. As bandwidth consumption is tracked locally between client and ingress node, and each zk-nym credit is rerandomised, there is no way that ingress Gateways would know that the zk-credential used by the client has been shared with other parties. This loophole highlights the need for stringent measures to counter such potential abuses within the system, without creating either speed bottlenecks (in the case of the Online model) or impacting the anonymity of the system. We can, however, mitigate this problem without doing either of these things.
- A malicious user purchases bandwidth and aggregates a valid zk-nym credential in the standard way, worth $10 of crypto/fiat. Subsequently, the malicious user proceeds to sell the credential to 100 users for $1 each, allowing each user to generate zk-nym tickets of 100MB from this **valid** credential. Under the offline approach, entry nodes forego double-spending checks; so long as the clients all used different ingress Gateways, all 100 users could access the network without obtaining a subscription. As bandwidth consumption is tracked locally between client and ingress node, and each zk-nym ticket is rerandomised, there is no way that ingress Gateways would know that the zk-credential used by the client has been shared with other parties. This loophole highlights the need for stringent measures to counter such potential abuses within the system, without creating either speed bottlenecks (in the case of the Online model) or impacting the anonymity of the system. We can, however, mitigate this problem without doing either of these things.

## Solution to Offline Double Spending
To efficiently prevent the fraudulent use of tickets within the Nym network, a two-tiered solution is in place that combines (1) the immediate detection of double-spending attempts at the level of individuals ingress Gateways and (2) subsequent identification and blacklisting of offending clients at the Quorum level.

### Entry Node Implementation: Real-Time Ticket Unspending Validation
Each spent zk-nym credit contains as an attribute a unique serial number, which is revealed in plaintext to the respective ingress Gateway. Each Gateway has a copy of a [Bloom Filter](https://www.geeksforgeeks.org/bloom-filters-introduction-and-python-implementation/) - on receiving a credit, it will check against its copy of a local database to check whether this serial number has already been seen. If so, it rejects the credit as being double-spent and the client's connection request is rejected. If not, it will add the serial number to its local DB.
Each spent zk-nym ticket contains as an attribute a unique serial number, which is revealed in plaintext to the respective ingress Gateway. Each Gateway has a copy of a [Bloom Filter](https://www.geeksforgeeks.org/bloom-filters-introduction-and-python-implementation/) - on receiving a ticket, it will check against its copy of a local database to check whether this serial number has already been seen. If so, it rejects the ticket as being double-spent and the client's connection request is rejected. If not, it will add the serial number to its local DB.

> Since each time a zk-nym credential is rerandomised its serial number is changed, the serial number being shared in no way identifies a client or user.

Expand All @@ -32,6 +32,6 @@ Each Gateway will periodically share their serial numbers with the Quorum and re
> Crucially, ingress Gateways refrain from extensive computations to identify the original ticket owner, and avoids broadcasting information about the double-spending attempt to other ingress Gateways. The entry node is also not involved in any global blacklisting process of the clients. The sole purpose of this check is to swiftly identify any attempts at double-spending and add the seen ticket's serial number to the local DB cache.

### Nym-API Implementation: Blacklisting and Penalties for Double-Spenders
All Gateways periodically forward the collected credits to the Quorum, enabling them to pinpoint and blacklist any clients who double spend. Upon receiving the credits, the Quorum appends all the incoming serial numbers to the global list of spend zk-nym serial numbers and proceed with the identification process for any malicious users engaging in double-spending.
All Gateways periodically forward the collected tickets to the Quorum, enabling them to pinpoint and blacklist any clients who double spend. Upon receiving the tickets, the Quorum appends all the incoming serial numbers to the global list of spend zk-nym serial numbers and proceed with the identification process for any malicious users engaging in double-spending.

This identification phase involves looking for instances of double spending, identifying the id of the double-spending client, and blacklisting this client by its id. Subsequently, when this client requests a new credential, their plaintext public identifier is included in the request. The Quorum then checks if this identifier is blacklisted. If it is, a new credential is not issued. Furthermore, since the PSCs are only attainable after depositing NYM as payment, the Quorum has the authority to withhold the deposited NYMs as a punitive measure for any detected instances of double-spending.
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,20 @@ import { Callout } from 'nextra/components'

# Rerandomisation & Incremental Spend

Each zk-nym credit will not be valid for the entire amount of data that the credential aggregated from the PSCs is; if the aggregated credential is worth (e.g.) 10GB of Mixnet data, each credit will be worth far less (e.g. 100MB). This amount will be globally uniform in order to avoid situations where differently sized credits allow for patterns to emerge.
Each ticket will not be valid for the entire amount of data that the ticketbook aggregated from the PSCs is; if the aggregated ticketbook is worth (e.g.) 10GB of Mixnet data, each ticket will be worth far less (e.g. 100MB). This amount will be globally uniform in order to avoid situations where differently sized tickets allow for patterns to emerge.

<Callout type="info" emoji="ℹ️">
The functionality included in the following code block examples were added to the [nym-cli tool](../tools/nym-cli.md) for illustrative purposes only: this is not necessarily how credentials will be accessed in the future.

**Furthermore, the `nym-cli` uses the words 'tickets' in place of 'credits' and 'ticketbook' in place of 'aggregated credential': this is wording that we are moving away from now in place of the simpler credential/credit.** This will be updated in the `nym-cli` tool in a future release.

The numbers used in this high level overview are for illustration purposes only. The figures used in production will potentially vary. Note that individual zkNym sizes will be uniform across the Network.
The numbers used in this high level overview are for illustration purposes only. The figures used in production will potentially vary. Note that individual ticket sizes will be uniform across the Network.
</Callout>


## Why not spend the entire credential at once?
## Why a 'ticketbook', not individual 'tickets', and why not spend them all at once?
This is to account for the need for a client to change their ingress Gateway, either because the Gateway itself has gone down / is not offering the required bandwidth, or because a user might simply want to split their traffic across multiple Gateways for extra privacy.

This means that clients are not tied to particular Gateways they have 'spent' their entire subscription amount with; if the ingress Gateway goes down, or the client simply wishes to use another ingress Gateway, the user has multiple other zk-nym credits they can use that account for their remaining purchased bandwidth.
This means that clients are not tied to particular Gateways they have 'spent' their entire subscription amount with; if the ingress Gateway goes down, or the client simply wishes to use another ingress Gateway, the user has multiple other tickets they can use that account for their remaining purchased bandwidth.

Going back to the `nym-cli` tool to illustrate this; we can generate multiple unlinkable credits ('tickets' on this command output) from a single aggregated credential ('ticketbook' below):
Going back to the `nym-cli` tool to illustrate this; we can generate multiple unlinkable tickets from a single ticketbook aggregated from PSCs:

```sh
❯ ./nym-cli ecash generate-ticket --credential-storage storage.db --provider 6qidVK21zpHD298jdDa1RRpbRozP29ENVyqcSbm6hQrG --full
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { Callout } from 'nextra/components'

# Unlinkability
Each time a credential is requested by an ingress Gateway to prove that a client has purchased data to send through the Mixnet, instead of sending that credential, the Requester's device will produce a zk-nym credit. This is a rereandomised value that is able to be verified as being legitimate (in that it was created by a valid root credential) but **not linked to any other credits**, either previously generated or to be generated in the future. This feature also allows for a credential to be split across multiple ingress Gateways / connections and [incrementally spent](./rerandomise.md) over time.
Each time a credential is requested by an ingress Gateway to prove that a client has purchased data to send through the Mixnet the Requester's device will produce a ticket. This is a rereandomised value that is able to be verified as being legitimate (in that it was created by a valid root ticketbook) but **not linked to any other tickets**, either previously generated or to be generated in the future. This feature also allows for a single ticketbook to allow access to be split across multiple ingress Gateways / connections and [incrementally spent](./rerandomise.md) over time.

<Callout type="info" emoji="ℹ️">

The functionality included in the following code block examples were added to the [nym-cli tool](../tools/nym-cli.md) for illustrative purposes only: this is not necessarily how credentials will be accessed in the future.

**Furthermore, the `nym-cli` uses the words 'tickets' in place of 'credits' and 'ticketbook' in place of 'aggregated credential': this is wording that we are moving away from now in place of the simpler credential/credit.** This will be updated in the `nym-cli` tool in a future release.

The numbers used in this high level overview are for illustration purposes only. The figures used in production will potentially vary. Note that individual zkNym sizes will be uniform across the Network.

</Callout>
Expand All @@ -24,7 +22,7 @@ PAYMENT FOR TICKET 3:
VfZAuVRRHekQYMvFevNAZmPPuwMAfEhTBY8TXatBysbrNXAg8euEGPpJvdbhNfQSznBb9nRSeBUSVoNTToSA6Uj5dXmJ7oE2rCB439DarLMWHWYfQNhw6yhWJhcg6bt7ebBYTs3vVeQgSB5kYuifzJF4QQmK6uJyTNPvpV1J6V8M32PBkGT3JpVB3GUGZiksETf7TaF9wAhMo2QAMxw5ZvaQVve5ea7Mane6cfb2Gx69SRff5zDfEQvKqKnyyZje4SGZgWUeHWVLhRjg4KMTJ3JcsHxEqj2k5qeGeyBbgzcuEtCpYvaytsz7nuZGJsT4Z87gB5Zq4NGuDmekuN977eRJvua2dASNWeHiAzVyvnS7ARN5cdUjjYKYiWgHaYrHGsv26WTDeiu4U3sdJMrLHGFY5ihX7f8sTZqD6Wx5AWjQNbEtKaVHymDogfLcwGCC42gQ2yhKfPUaWJ8H4yMB65YBDXGjATaUzcDmJcZKx8g31j2uTVNSFUesd5CRNEEcTNW7cSFFCishCD3T4eV9SuyZyEXAZ48pazPzc1BysBNHEXQNUEtEAZTKmpghC2pihhfDub6LnMJPo9DDdhCULCbcWbGAPc1vPekPaWvk7wrUTGwp5xoNUhQLW3MeJzMvrMSsqLdursCKB4h4Tk272WCStCPQwAKMYoxjWvMzxoUTTWCkhLKHruMtsehRnai4vhu13jbui6ji1F389gfazm4ctth2s4Yw3H3SaPtRETBfZNvZ7n5UV1MD6Q3qin92gT65iqXEi4zRN3woYcK6ZehiSvgUksdEFAUSxNMgNXKtHEYDS6kA37tn5JdBa2Ex2jLudFfhg6JBM226ZKyj65o6feYPgbJAR3jMCmQRHe6DSFb4aH895EowNMjfGUhwhmnbYB1djp7iFXxPP7575NAerhxEQ1WFnxTfoX7pu1Vc9YZb5priCAVbATCaDkECJsdedM45Vx96Jc6E5NWqD98RhMsPimVJkSfYJmRxH9qugica6WonFFb2YLvXYyhoBA1VHBcRqZJ5KHitS5AegYSoYprUfubMzcYo2hGVEQkGKAsFq6jZgCsbJoGLXt3No317vcowB5f3hqT9FjASHAzW2j8uJ9RRzX7XtrPhArwx4EyPgYzrvgG7xcenoSgQt8poa7aYky56eZTKHVUZgUEt6St32MjcivMvmNdWiAHHDc2ZxzTJHgeuCckX7n19vQ3XNLuXv9oGKNNCi8kHnT4tUnnGXNAWXWuyBgZKWUL8u3y41iW6dLYK3Pw5zfpKZTrq3q3bTLJRN5LnnUuFVnWsC3SNqa6VAAvhTGR9PzxLk8C6HeLP2AsYPpqeQwbaL3Ks6tvPdob3tQPWRBGL4uiKtNZ23tRYZGZLYFWZK7psRSZg5AETejKxztVzAuYovpVUiDq71o331tjqWWV1SzWT13Rd1uwz6nHtsjgao2863YaizKARcYr1j9MKtNfDs483yho6i7tbCRR9M4CPLqdiKEaRyVC1FP4F3sejA6nZTuAA35JWUzX6BBj7wgdypMLdMmmtcCZm3bRrF3GvJJs67U8JWRc6dnoGUDaD7rUu
```

Now lets generate another credit to spend either topping up once the previous one's data allowance has been used, or with another Gateway. Notice that the `ticket-index` is the same: this is generated from the same aggregated credential as the one above!
Now lets generate another ticket to spend either topping up once the previous one's data allowance has been used, or with another Gateway. Notice that the `ticket-index` is the same: this is generated from the same aggregated credential as the one above!

```sh
❯ ./nym-cli ecash generate-ticket --credential-storage storage.db --provider 6qidVK21zpHD298jdDa1RRpbRozP29ENVyqcSbm6hQrG --ticket-index=3
Expand All @@ -37,4 +35,4 @@ PAYMENT FOR TICKET 3:
Vev3SmwWtH5vbnejX5Zzc1EcxXAgveqHpKNN8arxXaWLhFcEpdcZ6n7qr3NrQUNURWsK2AsUiX8aSiGSjMPEY3iDE3aDYnjYERVow8RKUmQiYSKvz7v9cEJxt97JAHBfu9WYNHXTnLFSJwWuFtBdzY5dzPdzGckFenGCysa1ZBHGADHChDVXKoPHXxpn5qyJxmi48coUQDptR64QgkCeQ8RRZ396Lxw2NKFSjqavCMMDVm3g1rW7cYyPanBhkoAUzPU9KXX1rtmhD6F9gV89mGZ8fm7ByDuKuYU28seLQ7GkVKkhNeRW9XxbjSiyscTnMUzJ24R5VbSdr141BaquUHezdUTzmA2EjAtcyyiVrCMV13cc96CRbMXENP2soUzckFnh1qPnrfKCvX4JYkztq7UgPT2mZEnSTDW4C6Z2NVCNBPNLqUSYrU4id8Jzcp1mBxqJjdYcQ7P5fWJbT5Q9NAq44PCgfXpsUkNoj35QVQvKXKLb5oNGqnua5YC1WBPcENcpS7ZPWpk2hwe8VK4gNgnwQtWH2RPmWbvBREAV97vS1vKNHJyry9sD2PiMJGSmBnb1bKsGxR9UQN3YvRsdGHzyJHzAMTzxbFJBqMPmxjSHJR4UdwzhB81Ludu1RAffTvecWFxmWH5bNymCQjw3wey7Uequcxgyy8KAWYDzvHGwCZQbHQXghsYREiqquZWaa8hX3iTNBFUtEk8PRVT78MoFNdeBWNjsLr8zyZ5EGnf4kqmw3a91g5p5vywf6e3LgMu19VHjPSNtKMNXiatkPEVjsCuCppmV4sB7FsdKKWcMUSWLsdmrDBg9PStHr7NaJRzLL5E91gvysmB36Nob9cHeHSZj3wM4NVVjFfZeRqQf4bi7ahfXjeeBetgDpqx7JcbU6tTN4JpcGUpp7fp4MhTq7MeVQMLweGUVLqewKgAGzCvEmrK6dzLd3U1P9vkAAVZ3cCAKUywnHGxoxDeEfexP1g1EqJLtKNZVKPf7hSMWqGhoQ36K7y5GnyZ5YhQ7jcDME9orm5w4StoxoDdCPcjbakKG7UaTHuhd7tU1mUffXcEvVerkXoQK9SEaKvGks21RBhW86aHUzJWVbkiDzdaqjJWbmzLV8FKvNxNyzucoH2rq8LiHRMZfV1H3SkVSa4j2Ktw7ZGoQfdj8DgekxXSR2nHPfhybzKYXTBqFo2ACisxkjR4rXr9Xo6eYywQhQ1MP6aYgYCAXFGHPoFf7kx7Jns5sWvHRBdaMF65zeFF2m5NDuMWETtLgFfsyNgR84vfSqTfzj2gsUykRei7q9N4LKmiDwBALTAEcTvZpLtXBjc8JaB9PUeBw7DoSiSK376sGrQ9F6ZGTngXACNz1TbvYhtau4bDa6KC2Qn7wmoyrphpn7TtM1jdwGBxLcaEEWZKQHvWVfTyL2itjqnrcAZkxYdCj56oQYwpWfKQk3zJEUA6SYHqyJjaLNVK6u25j7969EWjdpTsJ8qSsZgXi3T7dQqiwintZbUUUKRq7egN1SGVnA6Wup91uKrYUWEWMqVu4g8ipmRsLD9iXHHr3yA21Cka7pqk1FxR9BFTAnkk1
```

These are both generated by the _same_ underlying credential and used in a way that they cannot be tied to each other. An ingress Gateway might (for instance) get 100 connection requests from 100 Nym clients, each validated with a zk-nym credi t. It has no way of knowing whether these are all from the same single subscription, or 100 different ones.
These are both generated by the _same_ underlying ticketbook and used in a way that they cannot be tied to each other. An ingress Gateway might (for instance) get 100 connection requests from 100 Nym clients, each validated with a ticket. It has no way of knowing whether these are all from the same single subscription, or 100 different ones.
Loading
Loading