Apply optimizations to tag generation + entangled tag generation
This commit is contained in:
parent
788270a02a
commit
1124ffc1a6
|
@ -29,6 +29,10 @@ bincode = "1.3.1"
|
||||||
name = "fuzzy_tags_benches"
|
name = "fuzzy_tags_benches"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "entangled"
|
||||||
|
harness = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
entangled = ["brute-force"]
|
entangled = ["brute-force"]
|
||||||
bulk_verify = ["rayon"]
|
bulk_verify = ["rayon"]
|
|
@ -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);
|
|
@ -1,5 +1,5 @@
|
||||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||||
use fuzzytags::RootSecret;
|
use fuzzytags::{RootSecret, TaggingKey};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
fn benchmark_generate_tag(c: &mut Criterion) {
|
fn benchmark_generate_tag(c: &mut Criterion) {
|
||||||
|
|
34
src/lib.rs
34
src/lib.rs
|
@ -428,6 +428,7 @@ impl<const GAMMA: u8> DetectionKey<{ GAMMA }> {
|
||||||
// See below for a full explanation as to the reason for this:
|
// See below for a full explanation as to the reason for this:
|
||||||
let w = RistrettoPoint::multiscalar_mul(&[m, tag.y], &[g, tag.u]);
|
let w = RistrettoPoint::multiscalar_mul(&[m, tag.y], &[g, tag.u]);
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
let pre_h = RootSecret::<GAMMA>::pre_h(tag.u, w);
|
||||||
|
|
||||||
// for each secret part...
|
// for each secret part...
|
||||||
let mut results: Vec<usize> = vec![];
|
let mut results: Vec<usize> = vec![];
|
||||||
|
@ -435,30 +436,21 @@ impl<const GAMMA: u8> DetectionKey<{ GAMMA }> {
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each_with(tx.clone(), |tx, (index, detection_key)| {
|
.for_each_with(tx.clone(), |tx, (index, detection_key)| {
|
||||||
let mut result = true;
|
let mut result = 0;
|
||||||
for (i, x_i) in detection_key.0.iter().enumerate() {
|
for (x_i, c_i) in detection_key.0.iter().zip(&tag.ciphertexts) {
|
||||||
// re-derive the key from the tag
|
// re-derive the key from the tag
|
||||||
let k_i = RootSecret::<GAMMA>::h(tag.u, tag.u.mul(x_i), w);
|
let k_i = RootSecret::<GAMMA>::post_h(pre_h.clone(), tag.u.mul(x_i));
|
||||||
|
|
||||||
// calculate the "original" plaintext
|
// calculate the "original" plaintext
|
||||||
let c_i = match tag.ciphertexts.get(i) {
|
let b_i = k_i ^ (c_i as u8);
|
||||||
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;
|
|
||||||
|
|
||||||
if b_i != 1 {
|
if b_i != 1 {
|
||||||
result = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// assert that the plaintext is all 1's
|
// 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) {
|
match tx.send(index) {
|
||||||
_ => {
|
_ => {
|
||||||
// TODO...surface this error...
|
// TODO...surface this error...
|
||||||
|
@ -514,11 +506,11 @@ impl<const GAMMA: u8> TaggingKey<{ GAMMA }> {
|
||||||
let u = g.mul(r);
|
let u = g.mul(r);
|
||||||
let z = Scalar::random(&mut rng);
|
let z = Scalar::random(&mut rng);
|
||||||
let w = g.mul(z);
|
let w = g.mul(z);
|
||||||
|
let pre_h = RootSecret::<GAMMA>::pre_h(u, w);
|
||||||
// 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 = RootSecret::<GAMMA>::h(u, h_i.mul(r), w);
|
let k_i = RootSecret::<GAMMA>::post_h(pre_h.clone(), h_i.mul(r));
|
||||||
// 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);
|
||||||
|
@ -579,14 +571,16 @@ impl<const GAMMA: u8> TaggingKey<{ GAMMA }> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = brute_force::Config::default();
|
let config = brute_force::Config::default();
|
||||||
|
|
||||||
let f = |z: &Scalar| {
|
let f = |z: &Scalar| {
|
||||||
let w = g.mul(z);
|
let w = g.mul(z);
|
||||||
|
let pre_h = RootSecret::<GAMMA>::pre_h(u, w);
|
||||||
let mut key = vec![];
|
let mut key = vec![];
|
||||||
for (i, precompute) in tagging_key_precomputes[0].iter().enumerate() {
|
for (i, precompute) in tagging_key_precomputes[0].iter().enumerate() {
|
||||||
let k_i = RootSecret::<GAMMA>::h(u, *precompute, w);
|
let k_i = RootSecret::<GAMMA>::post_h(pre_h.clone(), *precompute);
|
||||||
if i < length {
|
if i < length {
|
||||||
for precompute in tagging_key_precomputes.iter().skip(1) {
|
for precompute in tagging_key_precomputes.iter().skip(1) {
|
||||||
let n_k_i = RootSecret::<GAMMA>::h(u, precompute[i], w);
|
let n_k_i = RootSecret::<GAMMA>::post_h(pre_h.clone(), precompute[i]);
|
||||||
if k_i != n_k_i {
|
if k_i != n_k_i {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -614,7 +608,7 @@ impl<const GAMMA: u8> TaggingKey<{ GAMMA }> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{RootSecret, Tag};
|
use crate::{DetectionKey, RootSecret, Tag};
|
||||||
use bit_vec::BitVec;
|
use bit_vec::BitVec;
|
||||||
use curve25519_dalek::ristretto::RistrettoPoint;
|
use curve25519_dalek::ristretto::RistrettoPoint;
|
||||||
use curve25519_dalek::scalar::Scalar;
|
use curve25519_dalek::scalar::Scalar;
|
||||||
|
|
Loading…
Reference in New Issue