Version 0.2.0
- Performance Improvements - Removed KeyPair struct for a nicer API
This commit is contained in:
parent
e383dd8378
commit
c5bb0e2c88
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "fuzzytags"
|
name = "fuzzytags"
|
||||||
description = "a probabilistic cryptographic structure for metadata resistant tagging"
|
description = "a probabilistic cryptographic structure for metadata resistant tagging"
|
||||||
version = "0.1.4"
|
version = "0.2.0"
|
||||||
repository = "https://git.openprivacy.ca/openprivacy/fuzzytags"
|
repository = "https://git.openprivacy.ca/openprivacy/fuzzytags"
|
||||||
authors = ["Sarah Jamie Lewis <sarah@openprivacy.ca>"]
|
authors = ["Sarah Jamie Lewis <sarah@openprivacy.ca>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
22
README.md
22
README.md
|
@ -68,9 +68,9 @@ provided them (depending on the efficiency of the decryption method).
|
||||||
|
|
||||||
Generate a key pair:
|
Generate a key pair:
|
||||||
|
|
||||||
use fuzzytags::FuzzyTagKeyPair;
|
use fuzzytags::FuzzySecretKey;
|
||||||
let gamma = 24;
|
let gamma = 24;
|
||||||
let keypair = FuzzyTagKeyPair::generate(gamma);
|
let secret_key = FuzzySecretKey::generate(gamma);
|
||||||
|
|
||||||
`key.public_key` can be given to parties who you want to be able to communicate with you over a specific anonymous
|
`key.public_key` can be given to parties who you want to be able to communicate with you over a specific anonymous
|
||||||
messaging service / privacy-preserving application.
|
messaging service / privacy-preserving application.
|
||||||
|
@ -84,10 +84,10 @@ validate against a random public key with a maximum probability of _2^-gamma_.
|
||||||
|
|
||||||
Once in possession of a public key, a party in a metadata resistant app can use it to generate tags:
|
Once in possession of a public key, a party in a metadata resistant app can use it to generate tags:
|
||||||
|
|
||||||
use fuzzytags::FuzzyTagKeyPair;
|
use fuzzytags::FuzzySecretKey;
|
||||||
let gamma = 24;
|
let gamma = 24;
|
||||||
let keypair = FuzzyTagKeyPair::generate(gamma);
|
let secret_key = FuzzySecretKey::generate(gamma);
|
||||||
let public_key = keypair.public_key.clone();
|
let public_key = secret_key.public_key();
|
||||||
|
|
||||||
// Give public key to a another party...
|
// Give public key to a another party...
|
||||||
// and then they can do...
|
// and then they can do...
|
||||||
|
@ -101,12 +101,12 @@ First it is necessary to extract a detection key for a given false positive prob
|
||||||
|
|
||||||
This extracted key can then be given to an adversarial server. The server can then test a given tag against the detection key e.g.:
|
This extracted key can then be given to an adversarial server. The server can then test a given tag against the detection key e.g.:
|
||||||
|
|
||||||
use fuzzytags::FuzzyTagKeyPair;
|
use fuzzytags::FuzzySecretKey;
|
||||||
let gamma = 24;
|
let gamma = 24;
|
||||||
let keypair = FuzzyTagKeyPair::generate(gamma);
|
let secret_key = FuzzySecretKey::generate(gamma);
|
||||||
let public_key = keypair.public_key.clone();
|
let public_key = secret_key.public_key();
|
||||||
// extract a detection key
|
// extract a detection key
|
||||||
let detection_key = keypair.extract(5);
|
let detection_key = secret_key.extract(5);
|
||||||
|
|
||||||
// Give public key to a another party...
|
// Give public key to a another party...
|
||||||
// and then they can do...
|
// and then they can do...
|
||||||
|
@ -129,3 +129,7 @@ Results will be in `target/criterion/report/index.html`.
|
||||||
|
|
||||||
For more guidance on integrating fuzzytags into a privacy preserving application see [documentation](https://docs.rs/fuzzytags/#integrating-fuzzytags)
|
For more guidance on integrating fuzzytags into a privacy preserving application see [documentation](https://docs.rs/fuzzytags/#integrating-fuzzytags)
|
||||||
|
|
||||||
|
## Credits and Contributions
|
||||||
|
|
||||||
|
- Based on [Fuzzy Message Detection](https://eprint.iacr.org/2021/089) by Gabrielle Beck and Julia Len and Ian Miers and Matthew Green
|
||||||
|
- Performance & API improvements contributed by Henry de Valence
|
|
@ -1,23 +1,26 @@
|
||||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||||
use fuzzytags::FuzzyTagKeyPair;
|
use fuzzytags::FuzzySecretKey;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
fn benchmark_generate_tag(c: &mut Criterion) {
|
fn benchmark_generate_tag(c: &mut Criterion) {
|
||||||
let mut group = c.benchmark_group("generate_tags");
|
let mut group = c.benchmark_group("generate_tags");
|
||||||
group.measurement_time(Duration::new(10, 0));
|
group.measurement_time(Duration::new(10, 0));
|
||||||
let key = FuzzyTagKeyPair::generate(24);
|
let secret_key = FuzzySecretKey::generate(24);
|
||||||
for p in [5, 10, 15].iter() {
|
for p in [5, 10, 15].iter() {
|
||||||
group.bench_with_input(BenchmarkId::from_parameter(p), p, |b, _gamma| b.iter(|| key.public_key.generate_tag()));
|
let public_key = secret_key.public_key();
|
||||||
|
group.bench_with_input(BenchmarkId::from_parameter(p), p, |b, _gamma| b.iter(|| public_key.generate_tag()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn benchmark_test_tag(c: &mut Criterion) {
|
fn benchmark_test_tag(c: &mut Criterion) {
|
||||||
let mut group = c.benchmark_group("test_tags");
|
let mut group = c.benchmark_group("test_tags");
|
||||||
group.measurement_time(Duration::new(10, 0));
|
group.measurement_time(Duration::new(10, 0));
|
||||||
let key = FuzzyTagKeyPair::generate(24);
|
group.sample_size(500);
|
||||||
|
let secret_key = FuzzySecretKey::generate(24);
|
||||||
|
|
||||||
for p in [5, 10, 15].iter() {
|
for p in [5, 10, 15].iter() {
|
||||||
let tag = key.public_key.generate_tag();
|
let tag = secret_key.public_key().generate_tag();
|
||||||
let detection_key = key.extract(*p);
|
let detection_key = secret_key.extract(*p);
|
||||||
group.bench_with_input(BenchmarkId::from_parameter(p), p, |b, _gamma| b.iter(|| detection_key.test_tag(&tag)));
|
group.bench_with_input(BenchmarkId::from_parameter(p), p, |b, _gamma| b.iter(|| detection_key.test_tag(&tag)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
193
src/lib.rs
193
src/lib.rs
|
@ -46,20 +46,79 @@ impl Display for FuzzyTag {
|
||||||
/// The complete secret key. Can't directly be used for testing. Instead you will need to generate
|
/// The complete secret key. Can't directly be used for testing. Instead you will need to generate
|
||||||
/// a FuzzyDetectionKey using extract
|
/// a FuzzyDetectionKey using extract
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct FuzzySecretKey(Vec<Scalar>);
|
pub struct FuzzySecretKey {
|
||||||
|
/// 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)
|
||||||
|
secret_key: Vec<Scalar>,
|
||||||
|
/// the public key - this can be given to people who you want to contact you
|
||||||
|
public_key: FuzzyPublicKey,
|
||||||
|
}
|
||||||
|
|
||||||
impl FuzzySecretKey {
|
impl FuzzySecretKey {
|
||||||
|
/// Generate a new Key Pair given a security parameter `gamma`. Tags generated for a given
|
||||||
|
/// `FuzzyPublicKey::flag` will pass the `FuzzyDetectionKey::test` for other public
|
||||||
|
/// keys with probability $ 2 ^ -8 $
|
||||||
|
/// Example:
|
||||||
|
/// ```
|
||||||
|
/// use fuzzytags::{FuzzySecretKey};
|
||||||
|
/// let secret_key = FuzzySecretKey::generate(5);
|
||||||
|
/// ```
|
||||||
|
pub fn generate(gamma: usize) -> FuzzySecretKey {
|
||||||
|
let mut rng = OsRng::default();
|
||||||
|
let g = RISTRETTO_BASEPOINT_POINT;
|
||||||
|
let mut secret_key = vec![];
|
||||||
|
let mut p_keys = vec![];
|
||||||
|
for _i in 0..gamma {
|
||||||
|
let sk_i = Scalar::random(&mut rng);
|
||||||
|
let pk_i = g.mul(sk_i);
|
||||||
|
secret_key.push(sk_i);
|
||||||
|
p_keys.push(pk_i);
|
||||||
|
}
|
||||||
|
FuzzySecretKey {
|
||||||
|
secret_key,
|
||||||
|
public_key: FuzzyPublicKey { 0: p_keys },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// extract a detection key for a given false positive (p = 2^-n)
|
/// extract a detection key for a given false positive (p = 2^-n)
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// use fuzzytags::{FuzzyTagKeyPair};
|
/// use fuzzytags::{FuzzySecretKey};
|
||||||
/// let keypair = FuzzyTagKeyPair::generate(24);
|
/// let secret_key = FuzzySecretKey::generate(24);
|
||||||
/// let detection_key = keypair.extract(2);
|
/// let detection_key = secret_key.extract(2);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn extract(&self, n: usize) -> FuzzyDetectionKey {
|
pub fn extract(&self, n: usize) -> FuzzyDetectionKey {
|
||||||
let parts = self.0.iter().take(n).cloned().collect();
|
let parts = self.secret_key.iter().take(n).cloned().collect();
|
||||||
FuzzyDetectionKey { 0: parts }
|
FuzzyDetectionKey { 0: parts }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// derive the public key for this key
|
||||||
|
/// Example:
|
||||||
|
/// ```
|
||||||
|
/// use fuzzytags::FuzzySecretKey;
|
||||||
|
/// let secret_key = FuzzySecretKey::generate(24);
|
||||||
|
/// let public_key = secret_key.public_key();
|
||||||
|
/// ```
|
||||||
|
pub fn public_key(&self) -> FuzzyPublicKey {
|
||||||
|
self.public_key.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// a hash function that takes 3 ristretto points as a parameter and outputs 0 or 1.
|
||||||
|
fn h(u: RistrettoPoint, h: RistrettoPoint, w: RistrettoPoint) -> u8 {
|
||||||
|
let mut hash = sha3::Sha3_256::new();
|
||||||
|
hash.update(u.compress().as_bytes());
|
||||||
|
hash.update(h.compress().as_bytes());
|
||||||
|
hash.update(w.compress().as_bytes());
|
||||||
|
return hash.finalize().as_slice()[0] & 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// a hash function which takes a ristretto point and a vector of ciphertexts and outputs a
|
||||||
|
/// ristretto scalar.
|
||||||
|
fn g(u: RistrettoPoint, points: &BitVec) -> Scalar {
|
||||||
|
let mut input = points.to_bytes().as_slice().to_vec();
|
||||||
|
input.extend_from_slice(u.compress().as_bytes());
|
||||||
|
Scalar::hash_from_bytes::<Sha3_512>(input.as_slice())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of "secret" data that can be used to determine if a `FuzzyTag` was intended for
|
/// A collection of "secret" data that can be used to determine if a `FuzzyTag` was intended for
|
||||||
|
@ -88,12 +147,12 @@ impl Display for FuzzyDetectionKey {
|
||||||
impl FuzzyDetectionKey {
|
impl FuzzyDetectionKey {
|
||||||
/// calculate the ideal false positive rate of this detection key
|
/// calculate the ideal false positive rate of this detection key
|
||||||
/// ```
|
/// ```
|
||||||
/// use fuzzytags::FuzzyTagKeyPair;
|
/// use fuzzytags::FuzzySecretKey;
|
||||||
/// let gamma = 24;
|
/// let gamma = 24;
|
||||||
/// let keypair = FuzzyTagKeyPair::generate(gamma);
|
/// let secret_key = FuzzySecretKey::generate(gamma);
|
||||||
/// let public_key = keypair.public_key.clone();
|
/// let public_key = secret_key.public_key();
|
||||||
/// // extract a detection key
|
/// // extract a detection key
|
||||||
/// let detection_key = keypair.extract(5);
|
/// let detection_key = secret_key.extract(5);
|
||||||
/// detection_key.false_positive_probability();
|
/// detection_key.false_positive_probability();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn false_positive_probability(&self) -> f64 {
|
pub fn false_positive_probability(&self) -> f64 {
|
||||||
|
@ -103,12 +162,12 @@ impl FuzzyDetectionKey {
|
||||||
/// returns true if the tag was intended for this key
|
/// returns true if the tag was intended for this key
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// use fuzzytags::FuzzyTagKeyPair;
|
/// use fuzzytags::FuzzySecretKey;
|
||||||
/// let gamma = 24;
|
/// let gamma = 24;
|
||||||
/// let keypair = FuzzyTagKeyPair::generate(gamma);
|
/// let secret_key = FuzzySecretKey::generate(gamma);
|
||||||
/// let public_key = keypair.public_key.clone();
|
/// let public_key = secret_key.public_key();
|
||||||
/// // extract a detection key
|
/// // extract a detection key
|
||||||
/// let detection_key = keypair.extract(5);
|
/// let detection_key = secret_key.extract(5);
|
||||||
///
|
///
|
||||||
/// // Give public key to a another party...
|
/// // Give public key to a another party...
|
||||||
/// // and then they can do...
|
/// // and then they can do...
|
||||||
|
@ -122,7 +181,7 @@ impl FuzzyDetectionKey {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn test_tag(&self, tag: &FuzzyTag) -> bool {
|
pub fn test_tag(&self, tag: &FuzzyTag) -> bool {
|
||||||
let m = FuzzyTagKeyPair::g(tag.u, &tag.ciphertexts);
|
let m = FuzzySecretKey::g(tag.u, &tag.ciphertexts);
|
||||||
|
|
||||||
let g = RISTRETTO_BASEPOINT_POINT;
|
let g = RISTRETTO_BASEPOINT_POINT;
|
||||||
|
|
||||||
|
@ -140,7 +199,7 @@ impl FuzzyDetectionKey {
|
||||||
let mut result = true;
|
let mut result = true;
|
||||||
for (i, x_i) in self.0.iter().enumerate() {
|
for (i, x_i) in self.0.iter().enumerate() {
|
||||||
// re-derive the key from the tag
|
// re-derive the key from the tag
|
||||||
let k_i = FuzzyTagKeyPair::h(tag.u, tag.u.mul(x_i), w);
|
let k_i = FuzzySecretKey::h(tag.u, tag.u.mul(x_i), w);
|
||||||
|
|
||||||
// calculate the "original" plaintext
|
// calculate the "original" plaintext
|
||||||
let c_i = match tag.ciphertexts.get(i) {
|
let c_i = match tag.ciphertexts.get(i) {
|
||||||
|
@ -178,9 +237,9 @@ impl FuzzyPublicKey {
|
||||||
/// generate a new tag for this public key
|
/// generate a new tag for this public key
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// use fuzzytags::{FuzzyTagKeyPair};
|
/// use fuzzytags::{FuzzySecretKey};
|
||||||
/// let keypair = FuzzyTagKeyPair::generate(24);
|
/// let secret_key = FuzzySecretKey::generate(24);
|
||||||
/// let public_key = keypair.public_key.clone(); // give this to a sender
|
/// let public_key = secret_key.public_key(); // give this to a sender
|
||||||
/// let tag = public_key.generate_tag();
|
/// let tag = public_key.generate_tag();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn generate_tag(&self) -> FuzzyTag {
|
pub fn generate_tag(&self) -> FuzzyTag {
|
||||||
|
@ -196,7 +255,7 @@ impl FuzzyPublicKey {
|
||||||
// construct the ciphertext portion of the tag
|
// construct the ciphertext portion of the tag
|
||||||
let mut ciphertexts = BitVec::new();
|
let mut ciphertexts = BitVec::new();
|
||||||
for (_i, h_i) in self.0.iter().enumerate() {
|
for (_i, h_i) in self.0.iter().enumerate() {
|
||||||
let k_i = FuzzyTagKeyPair::h(u, h_i.mul(r), w);
|
let k_i = FuzzySecretKey::h(u, h_i.mul(r), w);
|
||||||
// encrypt a plaintext of all 1's
|
// encrypt a plaintext of all 1's
|
||||||
let c_i = k_i ^ 0x01;
|
let c_i = k_i ^ 0x01;
|
||||||
ciphertexts.push(c_i == 0x01);
|
ciphertexts.push(c_i == 0x01);
|
||||||
|
@ -217,88 +276,22 @@ impl FuzzyPublicKey {
|
||||||
// used to derive the key.
|
// 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 = FuzzyTagKeyPair::g(u, &ciphertexts);
|
let m = FuzzySecretKey::g(u, &ciphertexts);
|
||||||
let y = r.invert().mul(z.sub(m));
|
let y = r.invert().mul(z.sub(m));
|
||||||
|
|
||||||
return FuzzyTag { u, y, ciphertexts };
|
return FuzzyTag { u, y, ciphertexts };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An identity keypair for generating and validating fuzzy meta tags.
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct FuzzyTagKeyPair {
|
|
||||||
/// 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 secret_key: FuzzySecretKey,
|
|
||||||
/// the public key - this can be given to people who you want to contact you
|
|
||||||
pub public_key: FuzzyPublicKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FuzzyTagKeyPair {
|
|
||||||
/// Generate a new Key Pair given a security parameter `gamma`. Tags generated for a given
|
|
||||||
/// `FuzzyPublicKey::flag` will pass the `FuzzyDetectionKey::test` for other public
|
|
||||||
/// keys with probability $ 2 ^ -8 $
|
|
||||||
/// Example:
|
|
||||||
/// ```
|
|
||||||
/// use fuzzytags::{FuzzyTagKeyPair};
|
|
||||||
/// let keypair = FuzzyTagKeyPair::generate(5);
|
|
||||||
/// ```
|
|
||||||
pub fn generate(gamma: usize) -> FuzzyTagKeyPair {
|
|
||||||
let mut rng = OsRng::default();
|
|
||||||
let g = RISTRETTO_BASEPOINT_POINT;
|
|
||||||
let mut s_keys = vec![];
|
|
||||||
let mut p_keys = vec![];
|
|
||||||
for _i in 0..gamma {
|
|
||||||
let sk_i = Scalar::random(&mut rng);
|
|
||||||
let pk_i = g.mul(sk_i);
|
|
||||||
s_keys.push(sk_i);
|
|
||||||
p_keys.push(pk_i);
|
|
||||||
}
|
|
||||||
FuzzyTagKeyPair {
|
|
||||||
secret_key: FuzzySecretKey { 0: s_keys },
|
|
||||||
public_key: FuzzyPublicKey { 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
|
|
||||||
/// Example:
|
|
||||||
/// ```
|
|
||||||
/// use fuzzytags::{FuzzyTagKeyPair};
|
|
||||||
/// let keypair = FuzzyTagKeyPair::generate(24);
|
|
||||||
/// let detection_key = keypair.extract(2);
|
|
||||||
/// ```
|
|
||||||
pub fn extract(&self, n: usize) -> FuzzyDetectionKey {
|
|
||||||
self.secret_key.extract(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// a hash function that takes 3 ristretto points as a parameter and outputs 0 or 1.
|
|
||||||
fn h(u: RistrettoPoint, h: RistrettoPoint, w: RistrettoPoint) -> u8 {
|
|
||||||
let mut hash = sha3::Sha3_256::new();
|
|
||||||
hash.update(u.compress().as_bytes());
|
|
||||||
hash.update(h.compress().as_bytes());
|
|
||||||
hash.update(w.compress().as_bytes());
|
|
||||||
return hash.finalize().as_slice()[0] & 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// a hash function which takes a ristretto point and a vector of ciphertexts and outputs a
|
|
||||||
/// ristretto scalar.
|
|
||||||
fn g(u: RistrettoPoint, points: &BitVec) -> Scalar {
|
|
||||||
let mut input = points.to_bytes().as_slice().to_vec();
|
|
||||||
input.extend_from_slice(u.compress().as_bytes());
|
|
||||||
Scalar::hash_from_bytes::<Sha3_512>(input.as_slice())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::FuzzyTagKeyPair;
|
use crate::FuzzySecretKey;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialization() {
|
fn test_serialization() {
|
||||||
let key = FuzzyTagKeyPair::generate(24);
|
let secret_key = FuzzySecretKey::generate(24);
|
||||||
let tag = key.public_key.generate_tag();
|
let tag = secret_key.public_key.generate_tag();
|
||||||
let detection_key = key.extract(10);
|
let detection_key = secret_key.extract(10);
|
||||||
println!("{}", serde_json::to_string(&tag).unwrap());
|
println!("{}", serde_json::to_string(&tag).unwrap());
|
||||||
println!("{}", serde_json::to_string(&detection_key).unwrap());
|
println!("{}", serde_json::to_string(&detection_key).unwrap());
|
||||||
}
|
}
|
||||||
|
@ -306,31 +299,31 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn correctness() {
|
fn correctness() {
|
||||||
let number_of_messages = 100;
|
let number_of_messages = 100;
|
||||||
let key = FuzzyTagKeyPair::generate(16);
|
let secret_key = FuzzySecretKey::generate(16);
|
||||||
for i in 0..number_of_messages {
|
for i in 0..number_of_messages {
|
||||||
let tag = key.public_key.generate_tag();
|
let tag = secret_key.public_key().generate_tag();
|
||||||
println!("{}: {}", i, tag);
|
println!("{}: {}", i, tag);
|
||||||
assert!(key.extract(5).test_tag(&tag));
|
assert!(secret_key.extract(5).test_tag(&tag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn false_postives() {
|
fn false_positives() {
|
||||||
let gamma = 8;
|
let gamma = 8;
|
||||||
let number_of_messages = 1000;
|
let number_of_messages = 1000;
|
||||||
let key = FuzzyTagKeyPair::generate(gamma);
|
let secret_key = FuzzySecretKey::generate(gamma);
|
||||||
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 = FuzzyTagKeyPair::generate(gamma);
|
let secret_key2 = FuzzySecretKey::generate(gamma);
|
||||||
let tag = key2.public_key.generate_tag();
|
let tag = secret_key2.public_key().generate_tag();
|
||||||
assert!(key2.extract(3).test_tag(&tag));
|
assert!(secret_key2.extract(3).test_tag(&tag));
|
||||||
if key.secret_key.extract(3).test_tag(&tag) == true {
|
if secret_key.extract(3).test_tag(&tag) == true {
|
||||||
false_positives += 1;
|
false_positives += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
"Expected False Positive Rate: {}\nActual False Positive Rate: {}",
|
"Expected False Positive Rate: {}\nActual False Positive Rate: {}",
|
||||||
key.secret_key.extract(3).false_positive_probability(),
|
secret_key.extract(3).false_positive_probability(),
|
||||||
(false_positives as f64 / number_of_messages as f64)
|
(false_positives as f64 / number_of_messages as f64)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue