fuzzytags/README.md

153 lines
7.5 KiB
Markdown
Raw Normal View History

2021-01-30 19:33:30 +00:00
# FuzzyTags
2021-01-29 21:49:52 +00:00
2021-01-30 02:47:49 +00:00
Anonymous messaging systems (and other privacy-preserving applications) often require a mechanism for one party
to learn that another party has messaged them.
2021-01-29 21:52:34 +00:00
2021-01-30 02:47:49 +00:00
Many schemes rely on a bandwidth-intensive "download everything and attempt-decryption" approach. Others rely on a trusted
3rd party, or non-collusion assumptions, to provide a "private" service.
2021-01-30 02:24:27 +00:00
It would be awesome if we could get an **untrusted**, **adversarial** server to do the work for us without compromising metadata-resistance!
2021-01-30 02:24:27 +00:00
**fuzzytags** is an experimental probabilistic cryptographic tagging structure to do just that!
2021-01-30 02:47:49 +00:00
Specifically **fuzzytags** provides the following properties:
* Correctness: Valid tags constructed for a specific public key will always validate when tested using a derived detection key.
* Fuzziness: Tags will produce false positives with probability _p_ related to the security property (_γ_) when tested against detection keys they
were not intended for.
* Security: An adversarial server with access to the detection key **is unable to distinguish false positives from true positives**. (Detection Ambiguity)
2021-01-30 02:47:49 +00:00
## Security (hic sunt dracones)
This crate provides an experimental implementation of the `FMD2` scheme described in ["Fuzzy Message Detection"](https://eprint.iacr.org/2021/089). Using
Ristretto as the prime order group.
This code has not undergone any significant review.
Further, the properties provided by this system are highly dependent on selecting a **false positive rate** _p_ and
**scheme constant** _γ_ for your system. There is no one-size-fits-all approach.
2021-01-30 02:47:49 +00:00
If _p_ is too low, then the probability of false positives will be very high.
2021-01-30 02:47:49 +00:00
If _p_ is too high, then an adversarial server will be able to link messages to recipients with low probability.
2021-01-30 02:47:49 +00:00
Likewise a large _γ_ means higher bandwidth costs, but a small _γ_ reveals more of the secret keys to the server and
increases false positives.
2021-01-30 02:47:49 +00:00
## More Detailed System Description
There exists a metadata resistant application that uses untrusted servers to mediate communication between parties.
Each party can be identified with a set of cryptographic identifiers and there exists methods in or external to the system
to distribute keys securely and authentically.
Now, instead of each party adopting a download-everything approach to metadata privacy (or invoking non-collusion
or other assumptions) we can leverage fuzzytags to reduce the number of messages downloaded from the server by each party
while maintaining a formalized concept of metadata privacy.
Every party generates a `FuzzyTagKeyPair`, consisting of a `FuzzyTagSecretKey` and a `FuzzyTagPublicKey`. These keys will
be generated with a parameter _γ_ that relates to the minimum false-positive probability 2^-γ.
When submitting messages to the server for an intended **recipient**, the **sender** will generate a new tag
from the **recipients** `FuzzyTagPublicKey`.
All parties will `extract` a `FuzzyTagDetectionKey` from their key pair. This key will be of length `n` and provide
a false positive detection probability of 0 <= 2^-n <= 2^-γ. This detection key can be given to an adversarial server.
When fetching new messages from the adversarial server, the server first runs a `test` of the tag of the message against
the parties' detection key. If the tag passes the test, the message (along with the tag) is provided to the **recipient**.
Finally, the **recipient** runs their own `test` of the tag against an extracted detection key such that
`FuzzyTagSecretKey == FuzzyTagDetectionKey` i.e. the probability of a false positive will be 2^-n == 2^-γ. This will
produce a subset of messages likely intended for the **recipient**, with a smaller probability of false positives.
Alternatively the **recipient** can simply try and decrypt every message in the subset of messages that the server
provided them (depending on the efficiency of the decryption method).
2021-01-30 02:47:49 +00:00
## Usage
Generate a key pair:
2021-01-30 07:09:02 +00:00
use fuzzytags::FuzzySecretKey;
2021-01-31 23:42:37 +00:00
let gamma = 24;
let secret_key = FuzzySecretKey::generate(gamma);
2021-01-30 02:47:49 +00:00
`key.public_key` can be given to parties who you want to be able to communicate with you over a specific anonymous
messaging service / privacy-preserving application.
`key.detection_key` can be given to untrusted _adversarial_ servers.
`gamma` is security property (_γ_) in the system. For a given gamma, a tag generated for a specific public key will
2021-01-31 23:42:37 +00:00
validate against a random public key with a maximum probability of _2^-gamma_.
2021-01-30 02:47:49 +00:00
## Generating Tags
Once in possession of a public key, a party in a metadata resistant app can use it to generate tags:
2021-01-30 07:09:02 +00:00
use fuzzytags::FuzzySecretKey;
2021-01-31 23:42:37 +00:00
let gamma = 24;
let secret_key = FuzzySecretKey::generate(gamma);
let public_key = secret_key.public_key();
2021-01-31 23:42:37 +00:00
// Give public key to a another party...
// and then they can do...
let tag = public_key.generate_tag();
2021-01-30 02:47:49 +00:00
These tags can then be attached to a message in a metadata resistant system.
2021-01-30 02:47:49 +00:00
## Testing Tags
2021-01-30 02:47:49 +00:00
2021-01-31 23:42:37 +00:00
First it is necessary to extract a detection key for a given false positive probability _0 <= 2^-n <= 2^-γ_.
2021-01-30 19:36:48 +00:00
This extracted key can then be given to an adversarial server. The server can then test a given tag against the detection key e.g.:
2021-01-30 02:47:49 +00:00
use fuzzytags::FuzzySecretKey;
2021-01-31 23:42:37 +00:00
let gamma = 24;
let secret_key = FuzzySecretKey::generate(gamma);
let public_key = secret_key.public_key();
2021-01-31 23:42:37 +00:00
// extract a detection key
let detection_key = secret_key.extract(5);
2021-01-31 23:42:37 +00:00
// Give public key to a another party...
// and then they can do...
let tag = public_key.generate_tag();
// The server can now do this:
if detection_key.test_tag(&tag) {
// the message attached to this tag *might* be for the party associated with the detection key
} else {
// the message attached to this tag is definitely *not* for the party associated with the detection key.
}
2021-02-03 00:19:20 +00:00
## Entangled Tags
When enabled with the `entangled` feature the `FuzzyPublicKey::generate_entangled_tag` function is available. This
allows you to generate tags that will validate against **multiple** detection keys from **distinct public keys** and
opens up applications like **multiple broadcast** and **deniable sending**.
2021-02-03 00:21:14 +00:00
2021-02-03 00:19:20 +00:00
use fuzzytags::{FuzzySecretKey, FuzzyPublicKey};
let secret_key_1 = FuzzySecretKey::generate(24);
let secret_key_2 = FuzzySecretKey::generate(24);
let public_key_1 = secret_key_1.public_key(); // give this to a sender
let public_key_2 = secret_key_2.public_key(); // give this to a sender
// Will validate for detection keys derived from both secret_key_1 and secret_key_2 up
// to n=8
2021-02-03 00:21:14 +00:00
#[cfg(feature = "entangled")]
2021-02-03 00:19:20 +00:00
let tag = FuzzyPublicKey::generate_entangled_tag(vec![public_key_1,public_key_2], 8);
2021-01-31 23:42:37 +00:00
## Benchmarks
We use [criterion](https://crates.io/crates/criterion) for benchmarking, and benchmarks can run using `cargo bench`
Results will be in `target/criterion/report/index.html`.
2021-01-29 21:52:34 +00:00
2021-01-31 23:42:37 +00:00
## Integrating fuzzytags
2021-01-31 21:21:44 +00:00
2021-01-31 23:42:37 +00:00
For more guidance on integrating fuzzytags into a privacy preserving application see [documentation](https://docs.rs/fuzzytags/#integrating-fuzzytags)
2021-01-31 21:21:44 +00:00
## Credits and Contributions
- Based on [Fuzzy Message Detection](https://eprint.iacr.org/2021/089) by Gabrielle Beck and Julia Len and Ian Miers and Matthew Green
- Performance & API improvements contributed by Henry de Valence
- Universal Tag Bug found by [Lee Bousfield](https://github.com/PlasmaPower/)