From 035201447fc7766622de35c1deaefde252251f54 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Fri, 29 Jan 2021 23:09:02 -0800 Subject: [PATCH] API changes, some more explanation --- Cargo.toml | 4 ++-- README.md | 8 ++++---- src/lib.rs | 28 ++++++++++++++++++++-------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7b190f8..38ec059 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,5 @@ hex = "0.4.2" rand = "0.7.3" curve25519-dalek = {version="3.0.0", features=["serde"]} sha3 = "0.9.1" -serde = { version = "1", default_features = false, features = ["derive"], optional = true } -bit-vec = "0.6.3" \ No newline at end of file +bit-vec = "0.6.3" + diff --git a/README.md b/README.md index 76b97b0..7912f6d 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ If _γ_ is too high, then an adversarial server will be able to link messages to ## Usage Generate a key pair: - + let gamma = 3; let key = FuzzyMetaTagKeyPair::generate(gamma); @@ -47,8 +47,8 @@ validate against a random public key with probability 2^-gamma. The actual value of a given application is specific to that application, the number of parties involved, the number of messages involved etc. ## Generating Tags - - let tag = public_key.flag() + + let tag = public_key.generate_tag(); This tag can be attached to a message in a metadata resistant system. @@ -56,7 +56,7 @@ This tag can be attached to a message in a metadata resistant system. An adversarial server can test a given tag against a detection key: - if detection_key.test(tag) { + if key.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. diff --git a/src/lib.rs b/src/lib.rs index 131051d..6b6855d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,8 @@ use std::ops::{Add, Mul, Sub}; /// * 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)] pub struct FuzzyMetaTag { u: RistrettoPoint, @@ -34,7 +36,7 @@ pub struct FuzzyMetaDetectionKey(Vec); impl FuzzyMetaDetectionKey { /// returns true if the tag was intended for this key - pub fn test(&self, tag: &FuzzyMetaTag) -> bool { + pub fn test_tag(&self, tag: &FuzzyMetaTag) -> bool { let m = FuzzyMetaTagKeyPair::g(tag.u, &tag.ciphertexts); let g = RISTRETTO_BASEPOINT_POINT; @@ -46,6 +48,7 @@ impl FuzzyMetaDetectionKey { // w = g^m + g^(r * 1/r * (z-m)) // w = g^m + g^(z-m) // w = g^z + // See below for a full explanation as to the reason for this: let w = g.mul(m).add(tag.u.mul(tag.y)); // for each secret key part... @@ -72,8 +75,8 @@ impl FuzzyMetaDetectionKey { pub struct FuzzyMetaPublicKey(Vec); impl FuzzyMetaPublicKey { - /// creates a new tag for this public key - pub fn flag(&self) -> FuzzyMetaTag { + /// generate a new tag for this public key + pub fn generate_tag(&self) -> FuzzyMetaTag { let mut rng = OsRng::default(); let g = RISTRETTO_BASEPOINT_POINT; @@ -91,11 +94,20 @@ impl FuzzyMetaPublicKey { ciphertexts.push(c_i == 0x01); } + // Without this next part, this scheme would not be CCA-secure. Consider a scheme with just + // u = ^r and and h_i^r = g^(x_i*r) + // An adversarial server with access to a Test oracle (i.e. the decryption key) may be able + // to maul a challenge ciphertext by e.g. replacing the order of the ciphertexts. + // From the paper: // "The value w corresponds to a chameleon hash [KR00] computed on the message (0,z), where z is chosen at random. // Once the ciphertext has been computed, we use a master trapdoor for the chameleon hash (which is part of the scheme’s secret key) in order to compute a collision (y,m) where m // is a hash of the remaining components of the ciphertext" + // Translated m is a challenge over the random element u and the ordered ciphertexts + // It is then used to construct a response y which can be used to recover w the random element + // 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 y = r.invert().mul(z.sub(m)); @@ -178,9 +190,9 @@ mod tests { let number_of_messages = 100; let key = FuzzyMetaTagKeyPair::generate(16); for i in 0..number_of_messages { - let tag = key.public_key.flag(); + let tag = key.public_key.generate_tag(); println!("{}: {}", i, tag); - assert!(key.detection_key.test(&tag)); + assert!(key.detection_key.test_tag(&tag)); } } @@ -191,9 +203,9 @@ mod tests { let mut false_positives = 0; for _i in 0..number_of_messages { let key2 = FuzzyMetaTagKeyPair::generate(3); - let tag = key2.public_key.flag(); - assert!(key2.detection_key.test(&tag)); - if key.detection_key.test(&tag) == true { + let tag = key2.public_key.generate_tag(); + assert!(key2.detection_key.test_tag(&tag)); + if key.detection_key.test_tag(&tag) == true { false_positives += 1; } }