/// A tag is a probabilistic cryptographic structure. When constructed for a given `FuzzyMetaPublicKey`
/// it will pass the `FuzzyMetaDetectionKey::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.
/// This system provides the following security properties:
/// - Correctness: Valid tags for a public key for a key pair always validate when tested against the secret key
/// - Fuzziness: Invalid matches should produce false positives with probability p related to the security property (γ)
/// - Security: An adversarial server with access to Test oracle (i.e. the detection key) is unable to distinguish false positives from true positives. (Detection Ambiguity)
#[derive(Debug)]
pubstructFuzzyMetaTag{
u: RistrettoPoint,
@ -17,6 +24,82 @@ pub struct FuzzyMetaTag {
ciphertexts: BitVec,
}
/// A collection of "secret" data that can be used to determine if a `FuzzyMetaTag` was intended for
/// the derived public key.
pubstructFuzzyMetaDetectionKey(Vec<Scalar>);
implFuzzyMetaDetectionKey{
/// returns true if the tag was intended for this key
/// A public identity that others can create tags for.
pubstructFuzzyMetaPublicKey(Vec<RistrettoPoint>);
implFuzzyMetaPublicKey{
/// creates a new tag for this public key
pubfnflag(&self)-> FuzzyMetaTag{
letmutrng=OsRng::default();
letg=RISTRETTO_BASEPOINT_POINT;
// generate some random points...
letr=Scalar::random(&mutrng);
letu=g.mul(r);
letz=Scalar::random(&mutrng);
letw=g.mul(z);
// construct the ciphertext portion of the tag
letmutciphertexts=BitVec::new();
for(_i,h_i)inself.0.iter().enumerate(){
letk_i=FuzzyMetaTagKeyPair::h(u,h_i.mul(r),w);
letc_i=k_i^0x01;
ciphertexts.push(c_i==0x01);
}
// 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 scheme’s secret key) in order to compute a collision (y,m) where m
// is a hash of the remaining components of the ciphertext"
// finally calculate a `y` = 1/r * (z-m) which will be used to re-derive `w`
letm=FuzzyMetaTagKeyPair::g(u,&ciphertexts);
lety=r.invert().mul(z.sub(m));
returnFuzzyMetaTag{u,y,ciphertexts};
}
}
implDisplayforFuzzyMetaTag{
fnfmt(&self,f: &mutFormatter<'_>)-> fmt::Result{
write!(
@ -29,14 +112,17 @@ impl Display for FuzzyMetaTag {
}
}
#[derive(Debug)]
pubstructFuzzyMetaTagKey{
s_keys: Vec<Scalar>,
p_keys: Vec<RistrettoPoint>,
/// An identity keypair for generating and validating fuzzy meta tags.
pubstructFuzzyMetaTagKeyPair{
pubdetection_key: FuzzyMetaDetectionKey,
pubpublic_key: FuzzyMetaPublicKey,
}
implFuzzyMetaTagKey{
pubfngenerate(gamma: usize)-> FuzzyMetaTagKey{
implFuzzyMetaTagKeyPair{
/// Generate a new Key Pair given a security parameter `gamma`. Tags generated for a given
/// `FuzzyMetaPublicKey::flag` will pass the `FuzzyMetaDetectionKey::test` for other public