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).
/** * This class implements key pair generation of the McEliece Public Key * Cryptosystem (McEliecePKC). */
public class McElieceCCA2KeyPairGenerator implements AsymmetricCipherKeyPairGenerator {
The OID of the algorithm.
/** * 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.
/** * 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); } }