Tidy up comments & Structure + Benchmarks

This commit is contained in:
Sarah Jamie Lewis 2021-02-02 20:50:00 -08:00
parent 362a9b4da8
commit b48838c8e3
2 changed files with 16 additions and 23 deletions

View File

@ -5,6 +5,7 @@ use std::time::Duration;
fn benchmark_generate_tag(c: &mut Criterion) {
let mut group = c.benchmark_group("generate_tags");
group.measurement_time(Duration::new(10, 0));
group.sample_size(1000);
let secret_key = FuzzySecretKey::generate(24);
for p in [5, 10, 15].iter() {
let public_key = secret_key.public_key();
@ -15,7 +16,7 @@ fn benchmark_generate_tag(c: &mut Criterion) {
fn benchmark_test_tag(c: &mut Criterion) {
let mut group = c.benchmark_group("test_tags");
group.measurement_time(Duration::new(10, 0));
group.sample_size(500);
group.sample_size(1000);
let secret_key = FuzzySecretKey::generate(24);
for p in [5, 10, 15].iter() {

View File

@ -17,13 +17,12 @@ use std::fmt;
use std::fmt::{Display, Formatter};
use std::ops::{Mul, Sub};
#[cfg(feature = "entangled")]
use std::sync::Arc;
#[cfg(feature = "entangled")]
use rayon::iter::ParallelIterator;
#[cfg(feature = "entangled")]
use rayon::prelude::IntoParallelIterator;
#[cfg(feature = "entangled")]
use std::sync::Arc;
/// A tag is a probabilistic cryptographic structure. When constructed for a given `FuzzyPublicKey`
/// it will pass the `FuzzyDetectionKey::test` 100% of the time. For other public keys
@ -299,8 +298,8 @@ impl FuzzyPublicKey {
#[cfg(feature = "entangled")]
/// WARNING: if you pass in a large length into this function it will take a long time!
/// This begins a very slow, but ,parallel search for a tag that will validate of the given
/// public keys up to a given false positive rate 2^-1
/// This begins a very slow, but parallel, search for a tag that will validate of the given
/// public keys up to a given false positive rate 2^-l
/// Example:
/// ```
/// use fuzzytags::{FuzzySecretKey, FuzzyPublicKey};
@ -310,6 +309,7 @@ impl FuzzyPublicKey {
/// let public_key_2 = secret_key_2.public_key(); // give this to a sender
/// // Will validate for detection keys derived from both secret_key_1 and secret_key_2 up
/// // to n=8
/// // Sender can now do...tag will validate on detection keys of length 8 or lower.
/// let tag = FuzzyPublicKey::generate_entangled_tag(vec![public_key_1,public_key_2], 8);
/// ```
pub fn generate_entangled_tag(public_keys: Vec<FuzzyPublicKey>, length: usize) -> FuzzyTag {
@ -335,13 +335,17 @@ impl FuzzyPublicKey {
let r = Scalar::random(&mut rng);
let u = g.mul(r);
let mut entangled = false;
// Set z to zero...
let mut z = Scalar::zero();
// construct the ciphertext portion of the tag
let mut ciphertexts = BitVec::new();
let mut attempts = 0;
// Keep track of how many attempts and whether we have succeeded...
let mut attempts = 0;
let mut entangled = false;
// Compute and cache some public points that we will be using over and over again
let mut public_key_precomputes = vec![];
for public_key in public_keys.iter() {
let mut precompute = vec![];
@ -351,6 +355,7 @@ impl FuzzyPublicKey {
public_key_precomputes.push(precompute);
}
// Try a 1000 different options and hope maybe one of them is the magic number...
while !entangled && attempts < 1000 {
attempts += 1;
ciphertexts = BitVec::new();
@ -380,25 +385,12 @@ impl FuzzyPublicKey {
}
}
// If we are not entangled then at this point we return an error
if entangled == false {
return Err(());
}
// Without this next part, this scheme would not be CCA-secure. Consider a scheme with just
// u = ^r and and h_i^r = g^(x_i*r)
// An adversarial server with access to a Test oracle (i.e. the decryption key) may be able
// to maul a challenge ciphertext by e.g. replacing the order of the ciphertexts.
// From the paper:
// "The value w corresponds to a chameleon hash [KR00] computed on the message (0,z), where z is chosen at random.
// Once the ciphertext has been computed, we use a master trapdoor for the chameleon hash (which is part of the schemes secret key) in order to compute a collision (y,m) where m
// is a hash of the remaining components of the ciphertext"
// Translated m is a challenge over the random element u and the ordered ciphertexts
// It is then used to construct a response y which can be used to recover w the random element
// used to derive the key.
// finally calculate a `y` = 1/r * (z-m) which will be used to re-derive `w`
// This is the same as generate_tag, kept separate to avoid over-decomposition
let m = FuzzySecretKey::g(u, &ciphertexts);
let y = r.invert().mul(z.sub(m));