blob: b52370d2a9b6d0b9edffc1caf7ce88afc25ea316 [file] [log] [blame]
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;
/**
* This class implements key pair generation of the McEliece Public Key
* Cryptosystem (McEliecePKC).
*/
public class McElieceCCA2KeyPairGenerator
implements AsymmetricCipherKeyPairGenerator
{
/**
* The OID of the algorithm.
*/
public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2";
private McElieceCCA2KeyGenerationParameters mcElieceCCA2Params;
// the extension degree of the finite field GF(2^m)
private int m;
// the length of the code
private int n;
// the error correction capability
private int t;
// the field polynomial
private int fieldPoly;
// the source of randomness
private SecureRandom random;
// flag indicating whether the key pair generator has been initialized
private boolean initialized = false;
/**
* Default initialization of the key pair generator.
*/
private void initializeDefault()
{
McElieceCCA2KeyGenerationParameters mcCCA2Params = new McElieceCCA2KeyGenerationParameters(CryptoServicesRegistrar.getSecureRandom(), new McElieceCCA2Parameters());
init(mcCCA2Params);
}
// TODO
public void init(
KeyGenerationParameters param)
{
this.mcElieceCCA2Params = (McElieceCCA2KeyGenerationParameters)param;
// set source of randomness
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();
}
// finite field GF(2^m)
GF2mField field = new GF2mField(m, fieldPoly);
// irreducible Goppa polynomial
PolynomialGF2mSmallM gp = new PolynomialGF2mSmallM(field, t,
PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, random);
// generate canonical check matrix
GF2Matrix h = GoppaCode.createCanonicalCheckMatrix(field, gp);
// compute short systematic form of check matrix
MaMaPe mmp = GoppaCode.computeSystematicForm(h, random);
GF2Matrix shortH = mmp.getSecondMatrix();
Permutation p = mmp.getPermutation();
// compute short systematic form of generator matrix
GF2Matrix shortG = (GF2Matrix)shortH.computeTranspose();
// obtain number of rows of G (= dimension of the code)
int k = shortG.getNumRows();
// generate keys
McElieceCCA2PublicKeyParameters pubKey = new McElieceCCA2PublicKeyParameters(n, t, shortG, mcElieceCCA2Params.getParameters().getDigest());
McElieceCCA2PrivateKeyParameters privKey = new McElieceCCA2PrivateKeyParameters(n, k, field, gp, p, mcElieceCCA2Params.getParameters().getDigest());
// return key pair
return new AsymmetricCipherKeyPair(pubKey, privKey);
}
}