API changes, some more explanation

This commit is contained in:
Sarah Jamie Lewis 2021-01-29 23:09:02 -08:00
parent 13af02641c
commit 035201447f
3 changed files with 26 additions and 14 deletions

View File

@ -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"

View File

@ -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.

View File

@ -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 schemes 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;
}
}