class ZeroKnowledgeProver {

	public static ZeroKnowledgeProof createProof(final BigInteger a0, final BigInteger b0)
	{
		// Calculate A0 and B0
		final EcPoint A0 = curve.multiply(g, a0);
		final EcPoint B0 = curve.multiply(h, b0);
		
		// Chose random points
		final BigInteger r1 = RandomNumberGenerator.generateRandomInteger(curve.getR());
		final BigInteger r2 = RandomNumberGenerator.generateRandomInteger(curve.getR());
		
		// Compute powers
		final EcPoint p1 = curve.multiply(g, r1);
		final EcPoint p2 = curve.multiply(h, r2);
		final EcPoint sum = curve.addPoints(p1, p2);
		
		// Compute c
		final byte[] input = Parse.concatenate(g, h, sum);
		final MessageDigest digest;
		try {
			digest = MessageDigest.getInstance(HASH_ALGORITHM);
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException("Should not happen");
		}
		final BigInteger c = new BigInteger(1, digest.digest(input)).mod(curve.getR());
		
		// Compute sa and sb
		final BigInteger sa = (r1.subtract(c.multiply(a0))).mod(curve.getR());
		final BigInteger sb = (r2.subtract(c.multiply(b0))).mod(curve.getR());
		
		return new ZeroKnowledgeProof(A0, B0, c, sa, sb);
	}

}