Fix for Universal Tag Bug found by Lee Bousfield

This commit is contained in:
Sarah Jamie Lewis 2021-02-02 18:20:45 -08:00
parent 1084336c09
commit e19b99112e
3 changed files with 47 additions and 4 deletions

View File

@ -1,7 +1,7 @@
[package]
name = "fuzzytags"
description = "a probabilistic cryptographic structure for metadata resistant tagging"
version = "0.2.1"
version = "0.2.2"
repository = "https://git.openprivacy.ca/openprivacy/fuzzytags"
authors = ["Sarah Jamie Lewis <sarah@openprivacy.ca>"]
edition = "2018"

View File

@ -149,4 +149,5 @@ For more guidance on integrating fuzzytags into a privacy preserving application
## Credits and Contributions
- Based on [Fuzzy Message Detection](https://eprint.iacr.org/2021/089) by Gabrielle Beck and Julia Len and Ian Miers and Matthew Green
- Performance & API improvements contributed by Henry de Valence
- Performance & API improvements contributed by Henry de Valence
- Universal Tag Bug found by [Lee Bousfield](https://github.com/PlasmaPower/)

View File

@ -189,8 +189,15 @@ impl FuzzyDetectionKey {
/// }
/// ```
pub fn test_tag(&self, tag: &FuzzyTag) -> bool {
let m = FuzzySecretKey::g(tag.u, &tag.ciphertexts);
// A few checks to make sure the tag is well formed.
// All zeros in u or y can lead to a tag that validates against *all* public keys
// That doesn't seem like a great idea, so we return false to be safe.
// Zero values should never appear in well generated tags.
if tag.u.eq(&RistrettoPoint::default()) || tag.y.eq(&Scalar::zero()) {
return false;
}
let m = FuzzySecretKey::g(tag.u, &tag.ciphertexts);
let g = RISTRETTO_BASEPOINT_POINT;
// Re-derive w = g^z from the public tag.
@ -402,7 +409,10 @@ impl FuzzyPublicKey {
#[cfg(test)]
mod tests {
use crate::FuzzySecretKey;
use crate::{FuzzySecretKey, FuzzyTag};
use bit_vec::BitVec;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
#[test]
fn test_serialization() {
@ -440,6 +450,38 @@ mod tests {
}
}
fn gen_zero_tag_zero(max_gamma: usize) -> FuzzyTag {
let tag = FuzzyTag {
u: RistrettoPoint::default(),
y: Scalar::default(),
ciphertexts: BitVec::from_elem(max_gamma, false),
};
tag
}
fn gen_zero_tag_one(max_gamma: usize) -> FuzzyTag {
let mut tag = FuzzyTag {
u: RistrettoPoint::default(),
y: Scalar::default(),
ciphertexts: BitVec::from_elem(max_gamma, false),
};
tag.ciphertexts.set_all();
tag
}
#[test]
// Thanks to Lee Bousfield who noticed an all zeros or all ones tag would
// validate against a public key with 50% probability, allowing universal
// broadcast, which overall seems like a bad idea...
// Test to make sure that doesn't happen.
fn test_zero_tag() {
let secret_key = FuzzySecretKey::generate(24);
let tag = gen_zero_tag_zero(16);
assert_eq!(false, secret_key.extract(6).test_tag(&tag));
let tag = gen_zero_tag_one(16);
assert_eq!(false, secret_key.extract(6).test_tag(&tag));
}
#[test]
fn false_positives() {
let gamma = 8;