package org.bouncycastle.pqc.crypto.mceliece;
import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix;
import org.bouncycastle.pqc.math.linearalgebra.GF2mField;
import org.bouncycastle.pqc.math.linearalgebra.GoppaCode;
import org.bouncycastle.pqc.math.linearalgebra.GoppaCode.MaMaPe;
import org.bouncycastle.pqc.math.linearalgebra.Permutation;
import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM;
public class McElieceCCA2KeyPairGenerator
implements AsymmetricCipherKeyPairGenerator
{
public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2";
private McElieceCCA2KeyGenerationParameters mcElieceCCA2Params;
private int m;
private int n;
private int t;
private int fieldPoly;
private SecureRandom random;
private boolean initialized = false;
private void initializeDefault()
{
McElieceCCA2KeyGenerationParameters mcCCA2Params = new McElieceCCA2KeyGenerationParameters(CryptoServicesRegistrar.getSecureRandom(), new McElieceCCA2Parameters());
init(mcCCA2Params);
}
public void init(
KeyGenerationParameters param)
{
this.mcElieceCCA2Params = (McElieceCCA2KeyGenerationParameters)param;
this.random = CryptoServicesRegistrar.getSecureRandom();
this.m = this.mcElieceCCA2Params.getParameters().getM();
this.n = this.mcElieceCCA2Params.getParameters().getN();
this.t = this.mcElieceCCA2Params.getParameters().getT();
this.fieldPoly = this.mcElieceCCA2Params.getParameters().getFieldPoly();
this.initialized = true;
}
public AsymmetricCipherKeyPair generateKeyPair()
{
if (!initialized)
{
initializeDefault();
}
GF2mField field = new GF2mField(m, fieldPoly);
PolynomialGF2mSmallM gp = new PolynomialGF2mSmallM(field, t,
PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, random);
GF2Matrix h = GoppaCode.createCanonicalCheckMatrix(field, gp);
MaMaPe mmp = GoppaCode.computeSystematicForm(h, random);
GF2Matrix shortH = mmp.getSecondMatrix();
Permutation p = mmp.getPermutation();
GF2Matrix shortG = (GF2Matrix)shortH.computeTranspose();
int k = shortG.getNumRows();
McElieceCCA2PublicKeyParameters pubKey = new McElieceCCA2PublicKeyParameters(n, t, shortG, mcElieceCCA2Params.getParameters().getDigest());
McElieceCCA2PrivateKeyParameters privKey = new McElieceCCA2PrivateKeyParameters(n, k, field, gp, p, mcElieceCCA2Params.getParameters().getDigest());
return new AsymmetricCipherKeyPair(pubKey, privKey);
}
}