diff --git a/Cargo.toml b/Cargo.toml index afb6e30..c0a8669 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,10 @@ bincode = "1.3.1" name = "fuzzy_tags_benches" harness = false +[[bench]] +name = "entangled" +harness = false + [features] entangled = ["brute-force"] bulk_verify = ["rayon"] \ No newline at end of file diff --git a/benches/entangled.rs b/benches/entangled.rs new file mode 100644 index 0000000..c28cadf --- /dev/null +++ b/benches/entangled.rs @@ -0,0 +1,21 @@ +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use fuzzytags::{RootSecret, TaggingKey}; +use std::time::Duration; + +fn benchmark_entangled(c: &mut Criterion) { + let mut group = c.benchmark_group("entangling"); + group.measurement_time(Duration::new(10, 0)); + group.sample_size(10); + let secret_key_1 = RootSecret::<24>::generate(); + let secret_key_2 = RootSecret::<24>::generate(); + let public_key_1 = secret_key_1.tagging_key(); + let public_key_2 = secret_key_2.tagging_key(); + for p in [4, 8, 16, 20, 24].iter() { + group.bench_with_input(BenchmarkId::from_parameter(p), p, |b, _gamma| { + b.iter(|| TaggingKey::generate_entangled_tag(vec![public_key_1.clone(), public_key_2.clone()], *p)) + }); + } +} + +criterion_group!(benches, benchmark_entangled); +criterion_main!(benches); diff --git a/benches/fuzzy_tags_benches.rs b/benches/fuzzy_tags_benches.rs index 01c28b6..065bc77 100644 --- a/benches/fuzzy_tags_benches.rs +++ b/benches/fuzzy_tags_benches.rs @@ -1,5 +1,5 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; -use fuzzytags::RootSecret; +use fuzzytags::{RootSecret, TaggingKey}; use std::time::Duration; fn benchmark_generate_tag(c: &mut Criterion) { diff --git a/src/lib.rs b/src/lib.rs index 7ee49a5..acb84ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -428,6 +428,7 @@ impl DetectionKey<{ GAMMA }> { // See below for a full explanation as to the reason for this: let w = RistrettoPoint::multiscalar_mul(&[m, tag.y], &[g, tag.u]); let (tx, rx) = channel(); + let pre_h = RootSecret::::pre_h(tag.u, w); // for each secret part... let mut results: Vec = vec![]; @@ -435,30 +436,21 @@ impl DetectionKey<{ GAMMA }> { .par_iter() .enumerate() .for_each_with(tx.clone(), |tx, (index, detection_key)| { - let mut result = true; - for (i, x_i) in detection_key.0.iter().enumerate() { + let mut result = 0; + for (x_i, c_i) in detection_key.0.iter().zip(&tag.ciphertexts) { // re-derive the key from the tag - let k_i = RootSecret::::h(tag.u, tag.u.mul(x_i), w); + let k_i = RootSecret::::post_h(pre_h.clone(), tag.u.mul(x_i)); // calculate the "original" plaintext - let c_i = match tag.ciphertexts.get(i) { - Some(true) => 0x01, - Some(false) => 0x00, - _ => 0x00, - // we've run out of ciphertext, it doesn't really matter what we put here, the rest of the test will fail - // since the security of k_i is modelled as a random oracle, (k_i ^ 0) should also be random - }; - - let b_i = k_i ^ c_i; + let b_i = k_i ^ (c_i as u8); if b_i != 1 { - result = false; break; } // assert that the plaintext is all 1's - result = result & (b_i == 1); + result += 1; } - if result { + if result == detection_key.0.len() { match tx.send(index) { _ => { // TODO...surface this error... @@ -514,11 +506,11 @@ impl TaggingKey<{ GAMMA }> { let u = g.mul(r); let z = Scalar::random(&mut rng); let w = g.mul(z); - + let pre_h = RootSecret::::pre_h(u, w); // construct the ciphertext portion of the tag let mut ciphertexts = BitVec::new(); for (_i, h_i) in self.0.iter().enumerate() { - let k_i = RootSecret::::h(u, h_i.mul(r), w); + let k_i = RootSecret::::post_h(pre_h.clone(), h_i.mul(r)); // encrypt a plaintext of all 1's let c_i = k_i ^ 0x01; ciphertexts.push(c_i == 0x01); @@ -579,14 +571,16 @@ impl TaggingKey<{ GAMMA }> { } let config = brute_force::Config::default(); + let f = |z: &Scalar| { let w = g.mul(z); + let pre_h = RootSecret::::pre_h(u, w); let mut key = vec![]; for (i, precompute) in tagging_key_precomputes[0].iter().enumerate() { - let k_i = RootSecret::::h(u, *precompute, w); + let k_i = RootSecret::::post_h(pre_h.clone(), *precompute); if i < length { for precompute in tagging_key_precomputes.iter().skip(1) { - let n_k_i = RootSecret::::h(u, precompute[i], w); + let n_k_i = RootSecret::::post_h(pre_h.clone(), precompute[i]); if k_i != n_k_i { return None; } @@ -614,7 +608,7 @@ impl TaggingKey<{ GAMMA }> { #[cfg(test)] mod tests { - use crate::{RootSecret, Tag}; + use crate::{DetectionKey, RootSecret, Tag}; use bit_vec::BitVec; use curve25519_dalek::ristretto::RistrettoPoint; use curve25519_dalek::scalar::Scalar;