Adding entangled feature
This commit is contained in:
parent
21189374d7
commit
c1ce746da8
|
@ -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"]
|
||||
|
||||
|
|
16
README.md
16
README.md
|
@ -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`
|
||||
|
|
26
src/lib.rs
26
src/lib.rs
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue