diff --git a/Cargo.toml b/Cargo.toml index 141ccce..08964cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,12 @@ hex = "0.4.2" rand = "0.7.3" curve25519-dalek = {version="3.0.0", features=["serde"]} sha3 = "0.9.1" -bit-vec = "0.6.3" +bit-vec = {version="0.6.3", features=["serde"]} +serde = {version="1.0.123", features=["derive"]} [dev-dependencies] criterion = {version="0.3", features=["html_reports"]} +serde_json = "1.0.61" [[bench]] name = "fuzzy_tags_benches" diff --git a/src/lib.rs b/src/lib.rs index 2466e3b..f437435 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,8 @@ use curve25519_dalek::digest::Digest; use curve25519_dalek::ristretto::RistrettoPoint; use curve25519_dalek::scalar::Scalar; use rand::rngs::OsRng; +use serde::Deserialize; +use serde::Serialize; use sha3::Sha3_512; use std::fmt; use std::fmt::{Display, Formatter}; @@ -19,15 +21,28 @@ use std::ops::{Add, Mul, Sub}; /// * 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)] +#[derive(Debug, Serialize, Deserialize)] pub struct FuzzyMetaTag { 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); + +impl FuzzyMetaSecretKey { + /// extract a detection key for a given false positive (p = 2^-n) + pub fn extract(&self, n: usize) -> FuzzyMetaDetectionKey { + let parts = self.0.iter().take(n).cloned().collect(); + FuzzyMetaDetectionKey { 0: parts } + } +} + /// A collection of "secret" data that can be used to determine if a `FuzzyMetaTag` was intended for /// the derived public key with probability p +#[derive(Debug, Serialize, Deserialize)] pub struct FuzzyMetaDetectionKey(Vec); impl FuzzyMetaDetectionKey { @@ -133,7 +148,7 @@ impl Display for FuzzyMetaTag { pub struct FuzzyMetaTagKeyPair { /// 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 detection_key: FuzzyMetaDetectionKey, + pub secret_key: FuzzyMetaSecretKey, /// the public key - this can be given to people who you want to contact you pub public_key: FuzzyMetaPublicKey, } @@ -154,15 +169,15 @@ impl FuzzyMetaTagKeyPair { p_keys.push(pk_i); } FuzzyMetaTagKeyPair { - detection_key: FuzzyMetaDetectionKey { 0: s_keys }, + secret_key: FuzzyMetaSecretKey { 0: s_keys }, public_key: FuzzyMetaPublicKey { 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 { - let parts = self.detection_key.0.iter().take(n).cloned().collect(); - FuzzyMetaDetectionKey { 0: parts } + self.secret_key.extract(n) } /// a hash function that takes 3 risretto points as a parameter and outputs 0 or 1. @@ -190,6 +205,15 @@ impl FuzzyMetaTagKeyPair { mod tests { use crate::FuzzyMetaTagKeyPair; + #[test] + fn test_serialization() { + let key = FuzzyMetaTagKeyPair::generate(16); + let tag = key.public_key.generate_tag(); + let detection_key = key.extract(10); + println!("{}", serde_json::to_string(&tag).unwrap()); + println!("{}", serde_json::to_string(&detection_key).unwrap()); + } + #[test] fn correctness() { let number_of_messages = 100; @@ -211,7 +235,7 @@ mod tests { let key2 = FuzzyMetaTagKeyPair::generate(gamma); let tag = key2.public_key.generate_tag(); assert!(key2.extract(3).test_tag(&tag)); - if key.extract(3).test_tag(&tag) == true { + if key.secret_key.extract(3).test_tag(&tag) == true { false_positives += 1; } }