[wikipedia] In cryptography, the Boneh-Lynn-Shacham signature scheme allows a user to verify that a signer is authentic. The scheme uses a pairing function for verification and signatures are group elements in some elliptic curve. Working in an elliptic curve provides defense against index calculus attacks against allowing shorter signatures than FDH signatures. Signatures are often referred to as short signatures, BLS short signatures, or simply BLS signatures. The signature scheme is provably secure (that is, the scheme is existentially unforgeable under adaptive chosen-message attacks) assuming both the existence of random oracles and the intractability of the computational Diffie-Hellman problem.
In this page we will see how to:
The key generation algorithm selects a random integer x in Zr .
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 secret key Element x = pairing.getZr().newRandomElement(); // Generate the corresponding public key Element pk = g.powZn(x);
Given the private key x , and some message m , first we compute the hash of the message and then we map the hash to some element h of G1. We output the signature sig = h x .
Using jPBC we have:
// Map the hash of the message m to some element of G1 byte[] hash = ... // Generate an hash from m (48-bit hash) Element h = pairing.getG1().newElement().setFromHash(hash, 0, hash.length); // Generate the signature Element sig = h.powZn(x);
Given a signature sig and a public key g x , we verify that e(sig, g) =e(h, g x ) .
Again using jPBC::
// Map again the hash of the message m byte[] hash = ... // Generate an hash from m (48-bit hash) Element h = pairing.getG1().newElement().setFromHash(hash, 0, hash.length); // Verify the signature Element temp1 = pairing.pairing(sig, g); Element temp2 = pairing.pairing(h, pk); if (temp1.isEqual(temp2)) System.out.println("The signature is valid."); else System.out.println("The signature is NOT valid.");
You will find all the sources into the jpbc-crypto module.
import UTMAStrongParametersGenerator; import UTMAStrongParameters; // Init the generator. BLSParametersGenerator parametersGenerator = new BLSParametersGenerator(); parametersGenerator.init(curveParams); // Generate the parameters. BLSParameters parameters = parametersGenerator.generateParameters(); // Store the parameters in a file. FileOutputStream fileOutputStream = new FileOutputStream("bls.params"); parametersGenerator.store(fileOutputStream, parameters); fileOutputStream.flush(); fileOutputStream.close();
import UTMAStrongParametersGenerator; import UTMAStrongParameters; // Init the generator. BLSParametersGenerator parametersGenerator = new BLSParametersGenerator(); // Load the parameters from a file. FileInputStream fileInputStream = new FileInputStream("utmas.params"); BLSParameters parameters = parametersGenerator.load(fileInputStream); fileInputStream.close();
import UTMAStrongKeyPairGenerator; import UTMAStrongKeyGenerationParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; // Init the generator. BLSKeyPairGenerator keyPairGenerator = new BLSKeyPairGenerator(); keyPairGenerator.init(new BLSKeyGenerationParameters(null, parameters)); // Generate the key-pair. AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair(); // Store the key-pair. fileOutputStream = new FileOutputStream("bls_keypair.params"); keyPairGenerator.store(fileOutputStream, keyPair); fileOutputStream.flush(); fileOutputStream.close();
import UTMAStrongKeyPairGenerator; import UTMAStrongKeyGenerationParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; // Init the generator. BLSKeyPairGenerator keyPairGenerator = new BLSKeyPairGenerator(); // Load the key-pair from a file. fileInputStream = new FileInputStream("bls_keypair.params"); AsymmetricCipherKeyPair keyPair = keyPairGenerator.load(fileInputStream); fileInputStream.close();