Apply optimizations to tag generation + entangled tag generation

This commit is contained in:
Sarah Jamie Lewis 2021-05-20 01:11:07 -07:00
parent 788270a02a
commit 1124ffc1a6
4 changed files with 40 additions and 21 deletions

View File

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

21
benches/entangled.rs Normal file
View File

@ -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);

View File

@ -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) {

View File

@ -428,6 +428,7 @@ impl<const GAMMA: u8> 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::<GAMMA>::pre_h(tag.u, w);
// for each secret part...
let mut results: Vec<usize> = vec![];
@ -435,30 +436,21 @@ impl<const GAMMA: u8> 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::<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
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<const GAMMA: u8> TaggingKey<{ GAMMA }> {
let u = g.mul(r);
let z = Scalar::random(&mut rng);
let w = g.mul(z);
let pre_h = RootSecret::<GAMMA>::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::<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
let c_i = k_i ^ 0x01;
ciphertexts.push(c_i == 0x01);
@ -579,14 +571,16 @@ impl<const GAMMA: u8> TaggingKey<{ GAMMA }> {
}
let config = brute_force::Config::default();
let f = |z: &Scalar| {
let w = g.mul(z);
let pre_h = RootSecret::<GAMMA>::pre_h(u, w);
let mut key = vec![];
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 {
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 {
return None;
}
@ -614,7 +608,7 @@ impl<const GAMMA: u8> 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;