diff options
Diffstat (limited to 'libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java')
-rw-r--r-- | libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java b/libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java new file mode 100644 index 000000000..07db4cd6d --- /dev/null +++ b/libraries/spongycastle/core/src/main/java/org/spongycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java @@ -0,0 +1,151 @@ +package org.spongycastle.pqc.crypto.mceliece; + +import java.security.SecureRandom; + +import org.spongycastle.crypto.AsymmetricCipherKeyPair; +import org.spongycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.spongycastle.crypto.KeyGenerationParameters; +import org.spongycastle.pqc.math.linearalgebra.GF2Matrix; +import org.spongycastle.pqc.math.linearalgebra.GF2mField; +import org.spongycastle.pqc.math.linearalgebra.GoppaCode; +import org.spongycastle.pqc.math.linearalgebra.GoppaCode.MaMaPe; +import org.spongycastle.pqc.math.linearalgebra.Permutation; +import org.spongycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; +import org.spongycastle.pqc.math.linearalgebra.PolynomialRingGF2m; + + +/** + * This class implements key pair generation of the McEliece Public Key + * Cryptosystem (McEliecePKC). + */ +public class McElieceKeyPairGenerator + implements AsymmetricCipherKeyPairGenerator +{ + + + public McElieceKeyPairGenerator() + { + + } + + + /** + * The OID of the algorithm. + */ + private static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.1"; + + private McElieceKeyGenerationParameters mcElieceParams; + + // 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() + { + McElieceKeyGenerationParameters mcParams = new McElieceKeyGenerationParameters(new SecureRandom(), new McElieceParameters()); + initialize(mcParams); + } + + private void initialize( + KeyGenerationParameters param) + { + this.mcElieceParams = (McElieceKeyGenerationParameters)param; + + // set source of randomness + this.random = new SecureRandom(); + + this.m = this.mcElieceParams.getParameters().getM(); + this.n = this.mcElieceParams.getParameters().getN(); + this.t = this.mcElieceParams.getParameters().getT(); + this.fieldPoly = this.mcElieceParams.getParameters().getFieldPoly(); + this.initialized = true; + } + + + private AsymmetricCipherKeyPair genKeyPair() + { + + 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); + PolynomialRingGF2m ring = new PolynomialRingGF2m(field, gp); + + // matrix used to compute square roots in (GF(2^m))^t + PolynomialGF2mSmallM[] sqRootMatrix = ring.getSquareRootMatrix(); + + // 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 p1 = mmp.getPermutation(); + + // compute short systematic form of generator matrix + GF2Matrix shortG = (GF2Matrix)shortH.computeTranspose(); + + // extend to full systematic form + GF2Matrix gPrime = shortG.extendLeftCompactForm(); + + // obtain number of rows of G (= dimension of the code) + int k = shortG.getNumRows(); + + // generate random invertible (k x k)-matrix S and its inverse S^-1 + GF2Matrix[] matrixSandInverse = GF2Matrix + .createRandomRegularMatrixAndItsInverse(k, random); + + // generate random permutation P2 + Permutation p2 = new Permutation(n, random); + + // compute public matrix G=S*G'*P2 + GF2Matrix g = (GF2Matrix)matrixSandInverse[0].rightMultiply(gPrime); + g = (GF2Matrix)g.rightMultiply(p2); + + + // generate keys + McEliecePublicKeyParameters pubKey = new McEliecePublicKeyParameters(OID, n, t, g, mcElieceParams.getParameters()); + McEliecePrivateKeyParameters privKey = new McEliecePrivateKeyParameters(OID, n, k, + field, gp, matrixSandInverse[1], p1, p2, h, sqRootMatrix, mcElieceParams.getParameters()); + + // return key pair + return new AsymmetricCipherKeyPair(pubKey, privKey); + } + + public void init(KeyGenerationParameters param) + { + this.initialize(param); + + } + + public AsymmetricCipherKeyPair generateKeyPair() + { + return genKeyPair(); + } + +} |