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"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "entangled"
|
||||
harness = false
|
||||
|
||||
[features]
|
||||
entangled = ["brute-force"]
|
||||
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 fuzzytags::RootSecret;
|
||||
use fuzzytags::{RootSecret, TaggingKey};
|
||||
use std::time::Duration;
|
||||
|
||||
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:
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue