API changes, some more explanation
This commit is contained in:
parent
13af02641c
commit
035201447f
|
@ -11,5 +11,5 @@ hex = "0.4.2"
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
curve25519-dalek = {version="3.0.0", features=["serde"]}
|
curve25519-dalek = {version="3.0.0", features=["serde"]}
|
||||||
sha3 = "0.9.1"
|
sha3 = "0.9.1"
|
||||||
serde = { version = "1", default_features = false, features = ["derive"], optional = true }
|
bit-vec = "0.6.3"
|
||||||
bit-vec = "0.6.3"
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ If _γ_ is too high, then an adversarial server will be able to link messages to
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Generate a key pair:
|
Generate a key pair:
|
||||||
|
|
||||||
let gamma = 3;
|
let gamma = 3;
|
||||||
let key = FuzzyMetaTagKeyPair::generate(gamma);
|
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.
|
of a given application is specific to that application, the number of parties involved, the number of messages involved etc.
|
||||||
|
|
||||||
## Generating Tags
|
## 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.
|
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:
|
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
|
// the message attached to this tag *might* be for the party associated with the detection key
|
||||||
} else {
|
} else {
|
||||||
// the message attached to this tag is definitely *not* for the party associated with the detection key.
|
// the message attached to this tag is definitely *not* for the party associated with the detection key.
|
||||||
|
|
28
src/lib.rs
28
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 (_γ_)
|
/// * 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)
|
/// * 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)]
|
||||||
pub struct FuzzyMetaTag {
|
pub struct FuzzyMetaTag {
|
||||||
u: RistrettoPoint,
|
u: RistrettoPoint,
|
||||||
|
@ -34,7 +36,7 @@ pub struct FuzzyMetaDetectionKey(Vec<Scalar>);
|
||||||
|
|
||||||
impl FuzzyMetaDetectionKey {
|
impl FuzzyMetaDetectionKey {
|
||||||
/// returns true if the tag was intended for this key
|
/// 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 m = FuzzyMetaTagKeyPair::g(tag.u, &tag.ciphertexts);
|
||||||
|
|
||||||
let g = RISTRETTO_BASEPOINT_POINT;
|
let g = RISTRETTO_BASEPOINT_POINT;
|
||||||
|
@ -46,6 +48,7 @@ impl FuzzyMetaDetectionKey {
|
||||||
// w = g^m + g^(r * 1/r * (z-m))
|
// w = g^m + g^(r * 1/r * (z-m))
|
||||||
// w = g^m + g^(z-m)
|
// w = g^m + g^(z-m)
|
||||||
// w = g^z
|
// 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));
|
let w = g.mul(m).add(tag.u.mul(tag.y));
|
||||||
|
|
||||||
// for each secret key part...
|
// for each secret key part...
|
||||||
|
@ -72,8 +75,8 @@ impl FuzzyMetaDetectionKey {
|
||||||
pub struct FuzzyMetaPublicKey(Vec<RistrettoPoint>);
|
pub struct FuzzyMetaPublicKey(Vec<RistrettoPoint>);
|
||||||
|
|
||||||
impl FuzzyMetaPublicKey {
|
impl FuzzyMetaPublicKey {
|
||||||
/// creates a new tag for this public key
|
/// generate a new tag for this public key
|
||||||
pub fn flag(&self) -> FuzzyMetaTag {
|
pub fn generate_tag(&self) -> FuzzyMetaTag {
|
||||||
let mut rng = OsRng::default();
|
let mut rng = OsRng::default();
|
||||||
let g = RISTRETTO_BASEPOINT_POINT;
|
let g = RISTRETTO_BASEPOINT_POINT;
|
||||||
|
|
||||||
|
@ -91,11 +94,20 @@ impl FuzzyMetaPublicKey {
|
||||||
ciphertexts.push(c_i == 0x01);
|
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:
|
// From the paper:
|
||||||
// "The value w corresponds to a chameleon hash [KR00] computed on the message (0,z), where z is chosen at random.
|
// "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
|
// 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"
|
// 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`
|
// finally calculate a `y` = 1/r * (z-m) which will be used to re-derive `w`
|
||||||
let m = FuzzyMetaTagKeyPair::g(u, &ciphertexts);
|
let m = FuzzyMetaTagKeyPair::g(u, &ciphertexts);
|
||||||
let y = r.invert().mul(z.sub(m));
|
let y = r.invert().mul(z.sub(m));
|
||||||
|
@ -178,9 +190,9 @@ mod tests {
|
||||||
let number_of_messages = 100;
|
let number_of_messages = 100;
|
||||||
let key = FuzzyMetaTagKeyPair::generate(16);
|
let key = FuzzyMetaTagKeyPair::generate(16);
|
||||||
for i in 0..number_of_messages {
|
for i in 0..number_of_messages {
|
||||||
let tag = key.public_key.flag();
|
let tag = key.public_key.generate_tag();
|
||||||
println!("{}: {}", i, 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;
|
let mut false_positives = 0;
|
||||||
for _i in 0..number_of_messages {
|
for _i in 0..number_of_messages {
|
||||||
let key2 = FuzzyMetaTagKeyPair::generate(3);
|
let key2 = FuzzyMetaTagKeyPair::generate(3);
|
||||||
let tag = key2.public_key.flag();
|
let tag = key2.public_key.generate_tag();
|
||||||
assert!(key2.detection_key.test(&tag));
|
assert!(key2.detection_key.test_tag(&tag));
|
||||||
if key.detection_key.test(&tag) == true {
|
if key.detection_key.test_tag(&tag) == true {
|
||||||
false_positives += 1;
|
false_positives += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue