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"
|
||||
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"
|
||||
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
|
||||
|
||||
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.
|
||||
|
|
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 (_γ_)
|
||||
/// * 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<Scalar>);
|
|||
|
||||
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<RistrettoPoint>);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue