Monday, October 21, 2013

Random Secrets in Cryptographic Operations

Often we might need to generate random secrets and use them in cryptographic operations when we are implementing cryptographic protocols.

For an example, I recently had to implement Zero Knowledge Protocol with Pedersen Commitment where I need to generate a random secret and convert it to a BigInteger in order to compute the pedersen commitment.  

In this simple post, I thought of noting down the way I found how to do it in Java.

First, we can generate a random secret using "SecureRandom" in java. The article: "Proper Use of Java's SecureRandom" explains how to use SecureRandom properly in order to get it working in a uniform way across different platforms. 
In our example, we generate the random secret by feeding a pre-defined seed - our secret - into the pseudo random number generator of the SecureRandom, so that we can generate the same random secret at a later time as well.

Next, we can convert it to a BigInteger value so that we can use it in cryptographic computations.

Following code shows how the above two steps are implemented:
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;

public class Test {
    public static void main(String[] args) throws NoSuchProviderException, NoSuchAlgorithmException,
                                                  UnsupportedEncodingException {
        String password = "secret";
        //generate random secret using password as the seed
        SecureRandom randSec = SecureRandom.getInstance("SHA1PRNG", "SUN");
        randSec.setSeed(password.getBytes("us-ascii"));

        //create BigInteger of length 256 from the output of the SecureRandom's pseudo random number generator
        BigInteger randSecBI = new BigInteger(256, randSec);

    }
}



How to convert strings to big integers and vice versa

This is a very simple post on something I found useful in recently.

When creating cryptographic elements, we might need to convert Strings to BigIntegers and vice versa.

A good example is: when you want to hide a secret value using a commitment scheme such as pedersen commitment (I avoid explaining the pedersen commitment here and will leave it for a future post).

Following code demonstrate how you achieve the $subject in java:
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;

public class Test {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String identifier = "secretPW";
        //convert string to big integer
        BigInteger identifierBI = new BigInteger(identifier.getBytes("us-ascii"));
        System.out.println("Identifier: " + identifier + " converted to Big Integer: " + identifierBI);

        //convert the big integer back to identifier and verify
        String verifyIdentifier = new String(identifierBI.toByteArray());
        System.out.println("Big Integer converted back to string val: " + verifyIdentifier);
    }
}


Note: as in line 8 above, it is good to mention the encoding when converting the string to bytes so that your code will run in the same way even when deployed in different platforms.