Schemes - Untraceable Tags based on Mild Assumptions

Radio frequency identification (RFID) chips have been widely deployed in large-scale systems such as inventory control and supply chain management. While RFID technology has much advantage, however it may create new problems to privacy. Tag untraceability is a significant concern that needs to be addressed in deploying RFID-based system. Our construction is the first construction in the symmetric bilinear setting based on a mild assumption. That is our assumption is tautological in the generic group model and is ''efficiently falsifiable'' in the sense that its problem instances are stated non-interactively and concisely (i.e., independently of the number of adversarial queries and other large quantities).

In this page we will see:

  1. how to implement the weak construction of the scheme;
  2. how to use the strong construction, which can be find in the jpbc-crypto module, in the context of the Bouncy Castle framework.

Weak Construction

Public Information Generation

The public information generation algorithm select at random
  1. t1, t2, t3 and omega from Zr ;
  2. g0, g1 from G .
and then compute the following values:
  1. Omega=e(g,g) omega t1 t2 t3
  2. T1 = gt1
  3. T2 = gt2
  4. T3 = gt3
So we have that
  1. the Public Information (Pub) are ( g0, g1, Omega, T1, T2, T3 )
  2. ant the Master Secret Key (MSK) is ( omega, t1, t2, t3 )
Let's see how to do that using jPBC:
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;

// Init Pairings

CurveParams curveParams = new CurveParams().load("curve.properties");
Pairing pairing = PairingFactory.getPairing(curveParams);

// Generate system parameters

Element g = pairing.getG1().newRandomElement().getImmutable();

// Generate the MSK

Element omega = pairing.getZr().newRandomElement().getImmutable();
Element t1 = pairing.getZr().newRandomElement();
Element t2 = pairing.getZr().newRandomElement();
Element t3 = pairing.getZr().newRandomElement();

// Generate the Pub

Element g0 = pairing.getG1().newRandomElement();
Element g1 = pairing.getG1().newRandomElement();

Element T1 = g.powZn(t1);
Element T2 = g.powZn(t2);
Element T3 = g.powZn(t3);

Element Omega = pairing.pairing(g, g).pow(
    omega.mul(t1).mul(t2).mul(t3)
)

Key Generation

Encrypt

Decrypt

Randomize

Strong Construction

You will find all the sources into the jpbc-crypto module.

Generate and Store the Public Information

import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.generators.UTMAStrongParametersGenerator;
import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.params.UTMAStrongParameters;

// Init the generator.
UTMAStrongParametersGenerator pubInfoGenerator = new UTMAStrongParametersGenerator();
pubInfoGenerator.init(curveParams, new ElGamalParameters(p, g, l));

// Generate the parameters.
UTMAStrongParameters utmaParameters = pubInfoGenerator.generateParameters();

// Store the parameters in a file.
FileOutputStream fileOutputStream = new FileOutputStream("utmas.params");

pubInfoGenerator.store(fileOutputStream, utmaParameters);

fileOutputStream.flush();
fileOutputStream.close();
                

Load the Public Information

import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.generators.UTMAStrongParametersGenerator;
import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.params.UTMAStrongParameters;

// Init the generator.
UTMAStrongParametersGenerator pubInfoGenerator = new UTMAStrongParametersGenerator();

// Load the parameters from a file.
FileInputStream fileInputStream = new FileInputStream("utmas.params");

UTMAStrongParameters utmaParameters = pubInfoGenerator.load(fileInputStream);

fileInputStream.close();
                

Generate and Store a Key-Pair

import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.generators.UTMAStrongKeyPairGenerator;
import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.params.UTMAStrongKeyGenerationParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;

// Init the generator.
UTMAStrongKeyPairGenerator keyPairGenerator = new UTMAStrongKeyPairGenerator();
keyPairGenerator.init(new UTMAStrongKeyGenerationParameters(new SecureRandom(), utmaParameters));

// Generate the key-pair.
AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair();

// Store the key-pair.
fileOutputStream = new FileOutputStream("utmas_keypair.params");

utmaStrongKeyPairGenerator.store(fileOutputStream, keyPair);

fileOutputStream.flush();
fileOutputStream.close();
                

Load a Key-Pair

import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.generators.UTMAStrongKeyPairGenerator;
import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.params.UTMAStrongKeyGenerationParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;

// Init the generator.
UTMAStrongKeyPairGenerator keyPairGenerator = new UTMAStrongKeyPairGenerator();

// Load the key-pair from a file.
fileInputStream = new FileInputStream("utmas_keypair.params");

AsymmetricCipherKeyPair keyPair = utmaStrongKeyPairGenerator.load(fileInputStream);

fileInputStream.close();
                

Encrypt

import org.bouncycastle.crypto.AsymmetricBlockCipher;
import it.unisa.dia.gas.plaf.crypto.engines.MultiBlockAsymmetricBlockCipher;
import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.engines.UTMAStrongEngine;

// Init the engine.
AsymmetricBlockCipher strongEngine = new MultiBlockAsymmetricBlockCipher(
        new UTMAStrongEngine(),
        new PKCS7Padding()
);

// Encrypt
String message = "Hello World!!!";
byte[] messageAsBytes = message.getBytes();

strongEngine.init(true, keyPair.getPublic());
byte[] cipherText = strongEngine.processBlock(messageAsBytes, 0, messageAsBytes.length);
                

Decrypt

import org.bouncycastle.crypto.AsymmetricBlockCipher;
import it.unisa.dia.gas.plaf.crypto.engines.MultiBlockAsymmetricBlockCipher;
import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.engines.UTMAStrongEngine;

// Init the engine.
AsymmetricBlockCipher strongEngine = new MultiBlockAsymmetricBlockCipher(
        new UTMAStrongEngine(),
        new PKCS7Padding()
);

// Decrypt
strongEngine.init(false, keyPair.getPrivate());
byte[] plainText = strongEngine.processBlock(cipherText, 0, cipherText.length);
                

Randomize

import it.unisa.dia.gas.plaf.jpbc.crypto.rfid.utma.strong.engines.UTMAStrongRandomizer;

// Init the engine.
UTMAStrongRandomizer randomizer = new UTMAStrongRandomizer();
randomizer.init(utmaParameters);

// Re-Randomize
cipherText = randomizer.processBlock(cipherText, 0, cipherText.length);