Adding entangled feature

This commit is contained in:
Sarah Jamie Lewis 2021-02-02 16:19:20 -08:00
parent 21189374d7
commit c1ce746da8
3 changed files with 43 additions and 4 deletions

View File

@ -16,7 +16,7 @@ curve25519-dalek = {version="3.0.0", features=["serde"]}
sha3 = "0.9.1"
bit-vec = {version="0.6.3", features=["serde"]}
serde = {version="1.0.123", features=["derive"]}
rayon = "1.5.0"
rayon = {version="1.5.0", optional = true}
[dev-dependencies]
criterion = {version="0.3", features=["html_reports"]}
@ -26,3 +26,6 @@ serde_json = "1.0.61"
name = "fuzzy_tags_benches"
harness = false
[features]
entangled = ["rayon"]

View File

@ -119,6 +119,22 @@ This extracted key can then be given to an adversarial server. The server can th
// the message attached to this tag is definitely *not* for the party associated with the detection key.
}
## Entangled Tags
When enabled with the `entangled` feature the `FuzzyPublicKey::generate_entangled_tag` function is available. This
allows you to generate tags that will validate against **multiple** detection keys from **distinct public keys** and
opens up applications like **multiple broadcast** and **deniable sending**.
#[cfg(feature = "entangled")]
use fuzzytags::{FuzzySecretKey, FuzzyPublicKey};
let secret_key_1 = FuzzySecretKey::generate(24);
let secret_key_2 = FuzzySecretKey::generate(24);
let public_key_1 = secret_key_1.public_key(); // give this to a sender
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
let tag = FuzzyPublicKey::generate_entangled_tag(vec![public_key_1,public_key_2], 8);
## Benchmarks
We use [criterion](https://crates.io/crates/criterion) for benchmarking, and benchmarks can run using `cargo bench`

View File

@ -10,16 +10,21 @@ use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::MultiscalarMul;
use rand::rngs::OsRng;
use rayon::iter::ParallelIterator;
use rayon::prelude::IntoParallelIterator;
use serde::Deserialize;
use serde::Serialize;
use sha3::Sha3_512;
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;
/// 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
/// it will pass the test with probability `gamma` related to the security parameter of the system.
@ -285,9 +290,21 @@ impl FuzzyPublicKey {
return FuzzyTag { u, y, ciphertexts };
}
#[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
/// Example:
/// ```
/// use fuzzytags::{FuzzySecretKey, FuzzyPublicKey};
/// let secret_key_1 = FuzzySecretKey::generate(24);
/// let secret_key_2 = FuzzySecretKey::generate(24);
/// let public_key_1 = secret_key_1.public_key(); // give this to a sender
/// 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
/// 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 {
let arc_public_keys = Arc::new(public_keys);
loop {
@ -303,6 +320,7 @@ impl FuzzyPublicKey {
}
}
#[cfg(feature = "entangled")]
fn try_entangled_tag(public_keys: Arc<Vec<FuzzyPublicKey>>, length: usize) -> Result<FuzzyTag, ()> {
let mut rng = OsRng::default();
let g = RISTRETTO_BASEPOINT_POINT;
@ -384,7 +402,7 @@ impl FuzzyPublicKey {
#[cfg(test)]
mod tests {
use crate::{FuzzyPublicKey, FuzzySecretKey};
use crate::FuzzySecretKey;
#[test]
fn test_serialization() {
@ -396,7 +414,9 @@ mod tests {
}
#[test]
#[cfg(feature = "entangled")]
fn test_multiple() {
use crate::FuzzyPublicKey;
let secret_keys: Vec<FuzzySecretKey> = (0..3).map(|_x| FuzzySecretKey::generate(24)).collect();
let public_keys: Vec<FuzzyPublicKey> = secret_keys.iter().map(|x| x.public_key()).collect();
// it takes ~15 minutes on a standard desktop to find a length=24 match for 2 parties, so for testing let's keep things light