Switch to a Java-based test generator, which seems to work better.

This commit is contained in:
2018-05-06 21:22:10 -07:00
parent a2b4baa087
commit 3d767c3e13
3 changed files with 5767 additions and 4458 deletions

195
tests/dsa/Generator.java Normal file
View File

@@ -0,0 +1,195 @@
// Just because I always forget Java compilation:
// javac Generator.java -cp bcprov-ext-jdk15on-159.jar
// java -cp "bcprov-ext-jdk15on-159.jar:." Generator
// Also, go here:
// https://www.bouncycastle.org/latest_releases.html
//
import java.io.FileWriter;
import java.io.IOException;
import java.lang.InterruptedException;
import java.lang.Math;
import java.lang.Thread;
import java.math.BigInteger;
import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.generators.DSAKeyPairGenerator;
import org.bouncycastle.crypto.generators.DSAParametersGenerator;
import org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
import org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
import org.bouncycastle.crypto.signers.DSASigner;
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
class Generator {
private FileWriter out;
private SecureRandom rng;
final static int NUM_THREADS = 4;
public Generator(SecureRandom r, FileWriter o) {
rng = r;
out = o;
}
public void runTests(int lsize, int nsize, int count)
throws IOException, InterruptedException
{
Thread threads[] = new Thread[NUM_THREADS];
System.out.print("Generating L" + lsize + "N" + nsize + " tests ");
for(int i = 0; i < NUM_THREADS; i++) {
Runner runner = new Runner(lsize, nsize, count / NUM_THREADS, this);
Thread runThread = new Thread(runner);
runThread.start();
threads[i] = runThread;
}
for(Thread thread : threads) {
thread.join();
}
System.out.println(" done.");
}
public synchronized void output(DSAParameters params,
AsymmetricCipherKeyPair kp,
int digestsize,
byte[] message,
BigInteger[] rs)
throws IOException
{
DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic();
DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate();
out.write("p: " + params.getP().toString(16) + "\n");
out.write("q: " + params.getQ().toString(16) + "\n");
out.write("g: " + params.getG().toString(16) + "\n");
out.write("x: " + priv.getX().toString(16) + "\n");
out.write("y: " + pub.getY().toString(16) + "\n");
out.write("h: " + digestsize + "\n");
out.write("m: " + asHex(message) + "\n");
out.write("r: " + rs[0].toString(16) + "\n");
out.write("s: " + rs[1].toString(16) + "\n");
out.flush();
System.out.print(".");
System.out.flush();
}
private Digest appropriateDigest(int nsize)
throws IOException
{
switch(nsize) {
case 1: return new SHA1Digest();
case 160: return new SHA1Digest();
case 224: return new SHA224Digest();
case 256: return new SHA256Digest();
case 384: return new SHA384Digest();
case 512: return new SHA512Digest();
default:
throw new IOException("Bad digest size!");
}
}
private int randomDigestSize()
throws IOException
{
switch(getRandomChoice(5)) {
case 0: return 1;
case 1: return 224;
case 2: return 256;
case 3: return 384;
case 4: return 512;
default:
throw new IOException("The world broke.");
}
}
private int getRandomChoice(int modulus) {
byte randoms[] = new byte[2];
rng.nextBytes(randoms);
int random = ((int)randoms[0] << 8) + ((int)randoms[1]);
return (Math.abs(random) % modulus);
}
private String asHex(byte[] data) {
String result = "";
for(byte value : data) {
result = result + String.format("%02x", value);
}
return result;
}
public static void main(String[] args)
throws IOException, InterruptedException
{
SecureRandom rng = new SecureRandom();
FileWriter outfile = new FileWriter("signatures.test", false);
Generator gen = new Generator(rng, outfile);
gen.runTests(1024, 160, 500);
gen.runTests(2047, 224, 500);
gen.runTests(2048, 256, 250);
gen.runTests(3072, 256, 100);
}
private class Runner implements Runnable {
private int lsize;
private int nsize;
private int count;
private Generator parent;
public Runner(int lsize, int nsize, int count, Generator parent)
{
this.lsize = lsize;
this.nsize = nsize;
this.count = count;
this.parent = parent;
}
public void run()
{
for(int i = 0; i < count; i++) {
runTest();
}
}
private void runTest()
{
try {
DSAParameterGenerationParameters genparams =
new DSAParameterGenerationParameters(lsize, nsize, 80, rng);
DSAParametersGenerator gen =
new DSAParametersGenerator(parent.appropriateDigest(nsize));
gen.init(genparams);
DSAParameters params = gen.generateParameters();
DSAKeyGenerationParameters dsakeygenparams =
new DSAKeyGenerationParameters(rng, params);
DSAKeyPairGenerator keygen = new DSAKeyPairGenerator();
keygen.init(dsakeygenparams);
AsymmetricCipherKeyPair kp = keygen.generateKeyPair();
DSAPublicKeyParameters pub = (DSAPublicKeyParameters)kp.getPublic();
DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)kp.getPrivate();
int msgsize = getRandomChoice(1024);
byte message[] = new byte[msgsize];
rng.nextBytes(message);
int digestsize = randomDigestSize();
Digest msgdigest = appropriateDigest(digestsize);
HMacDSAKCalculator kgen = new HMacDSAKCalculator(msgdigest);
DSASigner signer = new DSASigner(kgen);
signer.init(true, priv);
BigInteger rs[] = signer.generateSignature(message);
parent.output(params, kp, digestsize, message, rs);
} catch(IOException exc) {
System.out.println("EXCEPTION!");
run();
}
}
}
}