diff --git a/Cargo.toml b/Cargo.toml index 08964cd..47c9291 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fuzzymetatag" +name = "fuzzytags" version = "0.1.0" authors = ["Sarah Jamie Lewis "] edition = "2018" diff --git a/README.md b/README.md index 3311306..5d7a7d3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# fuzzymetatag +# FuzzyTags Anonymous messaging systems (and other privacy-preserving applications) often require a mechanism for one party to learn that another party has messaged them. @@ -8,7 +8,7 @@ Many schemes rely on a bandwidth-intensive "download everything and attempt-decr It would be awesome if we could get an untrusted server to do the work for us without compromising metadata-resistance! -fuzzymetatag is a probabilistic cryptographic structure to do just that! Specifically it provides the following +**fuzzytags** is a probabilistic cryptographic structure to do just that! Specifically it provides the following properties: * Correctness: Valid tags constructed for a specific public key will always validate when tested using the detection key @@ -37,7 +37,7 @@ increases false positives. Generate a key pair: let gamma = 3; - let key = FuzzyMetaTagKeyPair::generate(gamma); + let key = FuzzyTagKeyPair::generate(gamma); `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. diff --git a/benches/fuzzy_tags_benches.rs b/benches/fuzzy_tags_benches.rs index 5f74daf..f23f074 100644 --- a/benches/fuzzy_tags_benches.rs +++ b/benches/fuzzy_tags_benches.rs @@ -1,11 +1,11 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; -use fuzzymetatag::FuzzyMetaTagKeyPair; +use fuzzytags::FuzzyTagKeyPair; use std::time::Duration; fn benchmark_generate_tag(c: &mut Criterion) { let mut group = c.benchmark_group("generate_tags"); group.measurement_time(Duration::new(10, 0)); - let key = FuzzyMetaTagKeyPair::generate(24); + let key = FuzzyTagKeyPair::generate(24); for p in [5, 10, 15].iter() { group.bench_with_input(BenchmarkId::from_parameter(p), p, |b, _gamma| b.iter(|| key.public_key.generate_tag())); } @@ -14,7 +14,7 @@ fn benchmark_generate_tag(c: &mut Criterion) { fn benchmark_test_tag(c: &mut Criterion) { let mut group = c.benchmark_group("test_tags"); group.measurement_time(Duration::new(10, 0)); - let key = FuzzyMetaTagKeyPair::generate(24); + let key = FuzzyTagKeyPair::generate(24); for p in [5, 10, 15].iter() { let tag = key.public_key.generate_tag(); let detection_key = key.extract(*p); diff --git a/src/lib.rs b/src/lib.rs index 36e1a3b..226ac95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,41 +14,41 @@ use std::fmt; use std::fmt::{Display, Formatter}; use std::ops::{Add, Mul, Sub}; -/// A tag is a probabilistic cryptographic structure. When constructed for a given `FuzzyMetaPublicKey` -/// it will pass the `FuzzyMetaDetectionKey::test` 100% of the time. For other public keys +/// A tag is a probabilistic cryptographic structure. When constructed for a given `FuzzyPublicKey` +/// it will pass the `FuzzyDetectionKey::test` 100% of the time. For other public keys /// it will pass the test with probability `gamma` related to the security parameter of the system. /// This system provides the following security properties: /// * Correctness: Valid tags constructed for a specific public key will always validate when tested using the detection key /// * Fuzziness: Invalid tags will produce false positives with probability _p_ related to the security property (_γ_) /// * Security: An adversarial server with access to the detection key is unable to distinguish false positives from true positives. (Detection Ambiguity) #[derive(Debug, Serialize, Deserialize)] -pub struct FuzzyMetaTag { +pub struct FuzzyTag { u: RistrettoPoint, y: Scalar, ciphertexts: BitVec, } /// The complete secret key. Can't directly be used for testing. Instead you will need to generate -/// a FuzzyMetaDetectionKey using extract -pub struct FuzzyMetaSecretKey(Vec); +/// a FuzzyDetectionKey using extract +pub struct FuzzySecretKey(Vec); -impl FuzzyMetaSecretKey { +impl FuzzySecretKey { /// extract a detection key for a given false positive (p = 2^-n) - pub fn extract(&self, n: usize) -> FuzzyMetaDetectionKey { + pub fn extract(&self, n: usize) -> FuzzyDetectionKey { let parts = self.0.iter().take(n).cloned().collect(); - FuzzyMetaDetectionKey { 0: parts } + FuzzyDetectionKey { 0: parts } } } -/// A collection of "secret" data that can be used to determine if a `FuzzyMetaTag` was intended for +/// A collection of "secret" data that can be used to determine if a `FuzzyTag` was intended for /// the derived public key with probability p #[derive(Debug, Serialize, Deserialize)] -pub struct FuzzyMetaDetectionKey(Vec); +pub struct FuzzyDetectionKey(Vec); -impl FuzzyMetaDetectionKey { +impl FuzzyDetectionKey { /// returns true if the tag was intended for this key - pub fn test_tag(&self, tag: &FuzzyMetaTag) -> bool { - let m = FuzzyMetaTagKeyPair::g(tag.u, &tag.ciphertexts); + pub fn test_tag(&self, tag: &FuzzyTag) -> bool { + let m = FuzzyTagKeyPair::g(tag.u, &tag.ciphertexts); let g = RISTRETTO_BASEPOINT_POINT; @@ -66,7 +66,7 @@ impl FuzzyMetaDetectionKey { let mut result = true; for (i, x_i) in self.0.iter().enumerate() { // re-derive the key from the tag - let k_i = FuzzyMetaTagKeyPair::h(tag.u, tag.u.mul(x_i), w); + let k_i = FuzzyTagKeyPair::h(tag.u, tag.u.mul(x_i), w); // calculate the "original" plaintext let c_i = match tag.ciphertexts.get(i) { @@ -87,11 +87,11 @@ impl FuzzyMetaDetectionKey { } /// A public identity that others can create tags for. -pub struct FuzzyMetaPublicKey(Vec); +pub struct FuzzyPublicKey(Vec); -impl FuzzyMetaPublicKey { +impl FuzzyPublicKey { /// generate a new tag for this public key - pub fn generate_tag(&self) -> FuzzyMetaTag { + pub fn generate_tag(&self) -> FuzzyTag { let mut rng = OsRng::default(); let g = RISTRETTO_BASEPOINT_POINT; @@ -104,7 +104,7 @@ impl FuzzyMetaPublicKey { // construct the ciphertext portion of the tag let mut ciphertexts = BitVec::new(); for (_i, h_i) in self.0.iter().enumerate() { - let k_i = FuzzyMetaTagKeyPair::h(u, h_i.mul(r), w); + let k_i = FuzzyTagKeyPair::h(u, h_i.mul(r), w); // encrypt a plaintext of all 1's let c_i = k_i ^ 0x01; ciphertexts.push(c_i == 0x01); @@ -125,14 +125,14 @@ impl FuzzyMetaPublicKey { // used to derive the key. // finally calculate a `y` = 1/r * (z-m) which will be used to re-derive `w` - let m = FuzzyMetaTagKeyPair::g(u, &ciphertexts); + let m = FuzzyTagKeyPair::g(u, &ciphertexts); let y = r.invert().mul(z.sub(m)); - return FuzzyMetaTag { u, y, ciphertexts }; + return FuzzyTag { u, y, ciphertexts }; } } -impl Display for FuzzyMetaTag { +impl Display for FuzzyTag { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( f, @@ -145,19 +145,19 @@ impl Display for FuzzyMetaTag { } /// An identity keypair for generating and validating fuzzy meta tags. -pub struct FuzzyMetaTagKeyPair { +pub struct FuzzyTagKeyPair { /// the detection key - this can be given to adversarial servers to help probabilistically /// filter messages (with a false-positive rate derived from γ and a 0% false negative rate) - pub secret_key: FuzzyMetaSecretKey, + pub secret_key: FuzzySecretKey, /// the public key - this can be given to people who you want to contact you - pub public_key: FuzzyMetaPublicKey, + pub public_key: FuzzyPublicKey, } -impl FuzzyMetaTagKeyPair { +impl FuzzyTagKeyPair { /// Generate a new Key Pair given a security parameter `gamma`. Tags generated for a given - /// `FuzzyMetaPublicKey::flag` will pass the `FuzzyMetaDetectionKey::test` for other public + /// `FuzzyPublicKey::flag` will pass the `FuzzyDetectionKey::test` for other public /// keys with probability $ 2 ^ -8 $ - pub fn generate(gamma: usize) -> FuzzyMetaTagKeyPair { + pub fn generate(gamma: usize) -> FuzzyTagKeyPair { let mut rng = OsRng::default(); let g = RISTRETTO_BASEPOINT_POINT; let mut s_keys = vec![]; @@ -168,15 +168,15 @@ impl FuzzyMetaTagKeyPair { s_keys.push(sk_i); p_keys.push(pk_i); } - FuzzyMetaTagKeyPair { - secret_key: FuzzyMetaSecretKey { 0: s_keys }, - public_key: FuzzyMetaPublicKey { 0: p_keys }, + FuzzyTagKeyPair { + secret_key: FuzzySecretKey { 0: s_keys }, + public_key: FuzzyPublicKey { 0: p_keys }, } } /// extract a detection key for a given false positive (p = 2^-n) /// a facade for an extraction of the encapsulated secret key - pub fn extract(&self, n: usize) -> FuzzyMetaDetectionKey { + pub fn extract(&self, n: usize) -> FuzzyDetectionKey { self.secret_key.extract(n) } @@ -203,11 +203,11 @@ impl FuzzyMetaTagKeyPair { #[cfg(test)] mod tests { - use crate::FuzzyMetaTagKeyPair; + use crate::FuzzyTagKeyPair; #[test] fn test_serialization() { - let key = FuzzyMetaTagKeyPair::generate(24); + let key = FuzzyTagKeyPair::generate(24); let tag = key.public_key.generate_tag(); let detection_key = key.extract(10); println!("{}", serde_json::to_string(&tag).unwrap()); @@ -217,7 +217,7 @@ mod tests { #[test] fn correctness() { let number_of_messages = 100; - let key = FuzzyMetaTagKeyPair::generate(16); + let key = FuzzyTagKeyPair::generate(16); for i in 0..number_of_messages { let tag = key.public_key.generate_tag(); println!("{}: {}", i, tag); @@ -229,10 +229,10 @@ mod tests { fn false_postives() { let gamma = 8; let number_of_messages = 1000; - let key = FuzzyMetaTagKeyPair::generate(gamma); + let key = FuzzyTagKeyPair::generate(gamma); let mut false_positives = 0; for _i in 0..number_of_messages { - let key2 = FuzzyMetaTagKeyPair::generate(gamma); + let key2 = FuzzyTagKeyPair::generate(gamma); let tag = key2.public_key.generate_tag(); assert!(key2.extract(3).test_tag(&tag)); if key.secret_key.extract(3).test_tag(&tag) == true {