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"
|
sha3 = "0.9.1"
|
||||||
bit-vec = {version="0.6.3", features=["serde"]}
|
bit-vec = {version="0.6.3", features=["serde"]}
|
||||||
serde = {version="1.0.123", features=["derive"]}
|
serde = {version="1.0.123", features=["derive"]}
|
||||||
rayon = "1.5.0"
|
rayon = {version="1.5.0", optional = true}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = {version="0.3", features=["html_reports"]}
|
criterion = {version="0.3", features=["html_reports"]}
|
||||||
|
@ -26,3 +26,6 @@ serde_json = "1.0.61"
|
||||||
name = "fuzzy_tags_benches"
|
name = "fuzzy_tags_benches"
|
||||||
harness = false
|
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.
|
// 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
|
## Benchmarks
|
||||||
|
|
||||||
We use [criterion](https://crates.io/crates/criterion) for benchmarking, and benchmarks can run using `cargo bench`
|
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::scalar::Scalar;
|
||||||
use curve25519_dalek::traits::MultiscalarMul;
|
use curve25519_dalek::traits::MultiscalarMul;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rayon::iter::ParallelIterator;
|
|
||||||
use rayon::prelude::IntoParallelIterator;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sha3::Sha3_512;
|
use sha3::Sha3_512;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::ops::{Mul, Sub};
|
use std::ops::{Mul, Sub};
|
||||||
|
|
||||||
|
#[cfg(feature = "entangled")]
|
||||||
use std::sync::Arc;
|
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`
|
/// 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 `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.
|
/// 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 };
|
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!
|
/// 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
|
/// 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
|
/// 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 {
|
pub fn generate_entangled_tag(public_keys: Vec<FuzzyPublicKey>, length: usize) -> FuzzyTag {
|
||||||
let arc_public_keys = Arc::new(public_keys);
|
let arc_public_keys = Arc::new(public_keys);
|
||||||
loop {
|
loop {
|
||||||
|
@ -303,6 +320,7 @@ impl FuzzyPublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "entangled")]
|
||||||
fn try_entangled_tag(public_keys: Arc<Vec<FuzzyPublicKey>>, length: usize) -> Result<FuzzyTag, ()> {
|
fn try_entangled_tag(public_keys: Arc<Vec<FuzzyPublicKey>>, length: usize) -> Result<FuzzyTag, ()> {
|
||||||
let mut rng = OsRng::default();
|
let mut rng = OsRng::default();
|
||||||
let g = RISTRETTO_BASEPOINT_POINT;
|
let g = RISTRETTO_BASEPOINT_POINT;
|
||||||
|
@ -384,7 +402,7 @@ impl FuzzyPublicKey {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{FuzzyPublicKey, FuzzySecretKey};
|
use crate::FuzzySecretKey;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialization() {
|
fn test_serialization() {
|
||||||
|
@ -396,7 +414,9 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(feature = "entangled")]
|
||||||
fn test_multiple() {
|
fn test_multiple() {
|
||||||
|
use crate::FuzzyPublicKey;
|
||||||
let secret_keys: Vec<FuzzySecretKey> = (0..3).map(|_x| FuzzySecretKey::generate(24)).collect();
|
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();
|
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
|
// 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