diff options
Diffstat (limited to 'core/src/main/java/org/bouncycastle/pqc/crypto/mceliece')
22 files changed, 0 insertions, 3000 deletions
diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/Conversions.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/Conversions.java deleted file mode 100644 index 752d51cc..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/Conversions.java +++ /dev/null @@ -1,236 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import java.math.BigInteger; - -import org.bouncycastle.pqc.math.linearalgebra.BigIntUtils; -import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; -import org.bouncycastle.pqc.math.linearalgebra.IntegerFunctions; - - -/** - * Provides methods for CCA2-Secure Conversions of McEliece PKCS - */ -final class Conversions -{ - private static final BigInteger ZERO = BigInteger.valueOf(0); - private static final BigInteger ONE = BigInteger.valueOf(1); - - /** - * Default constructor (private). - */ - private Conversions() - { - } - - /** - * Encode a number between 0 and (n|t) (binomial coefficient) into a binary - * vector of length n with weight t. The number is given as a byte array. - * Only the first s bits are used, where s = floor[log(n|t)]. - * - * @param n integer - * @param t integer - * @param m the message as a byte array - * @return the encoded message as {@link GF2Vector} - */ - public static GF2Vector encode(final int n, final int t, final byte[] m) - { - if (n < t) - { - throw new IllegalArgumentException("n < t"); - } - - // compute the binomial c = (n|t) - BigInteger c = IntegerFunctions.binomial(n, t); - // get the number encoded in m - BigInteger i = new BigInteger(1, m); - // compare - if (i.compareTo(c) >= 0) - { - throw new IllegalArgumentException("Encoded number too large."); - } - - GF2Vector result = new GF2Vector(n); - - int nn = n; - int tt = t; - for (int j = 0; j < n; j++) - { - c = c.multiply(BigInteger.valueOf(nn - tt)).divide( - BigInteger.valueOf(nn)); - nn--; - if (c.compareTo(i) <= 0) - { - result.setBit(j); - i = i.subtract(c); - tt--; - if (nn == tt) - { - c = ONE; - } - else - { - c = (c.multiply(BigInteger.valueOf(tt + 1))) - .divide(BigInteger.valueOf(nn - tt)); - } - } - } - - return result; - } - - /** - * Decode a binary vector of length n and weight t into a number between 0 - * and (n|t) (binomial coefficient). The result is given as a byte array of - * length floor[(s+7)/8], where s = floor[log(n|t)]. - * - * @param n integer - * @param t integer - * @param vec the binary vector - * @return the decoded vector as a byte array - */ - public static byte[] decode(int n, int t, GF2Vector vec) - { - if ((vec.getLength() != n) || (vec.getHammingWeight() != t)) - { - throw new IllegalArgumentException( - "vector has wrong length or hamming weight"); - } - int[] vecArray = vec.getVecArray(); - - BigInteger bc = IntegerFunctions.binomial(n, t); - BigInteger d = ZERO; - int nn = n; - int tt = t; - for (int i = 0; i < n; i++) - { - bc = bc.multiply(BigInteger.valueOf(nn - tt)).divide( - BigInteger.valueOf(nn)); - nn--; - - int q = i >> 5; - int e = vecArray[q] & (1 << (i & 0x1f)); - if (e != 0) - { - d = d.add(bc); - tt--; - if (nn == tt) - { - bc = ONE; - } - else - { - bc = bc.multiply(BigInteger.valueOf(tt + 1)).divide( - BigInteger.valueOf(nn - tt)); - } - - } - } - - return BigIntUtils.toMinimalByteArray(d); - } - - /** - * Compute a message representative of a message given as a vector of length - * <tt>n</tt> bit and of hamming weight <tt>t</tt>. The result is a - * byte array of length <tt>(s+7)/8</tt>, where - * <tt>s = floor[log(n|t)]</tt>. - * - * @param n integer - * @param t integer - * @param m the message vector as a byte array - * @return a message representative for <tt>m</tt> - */ - public static byte[] signConversion(int n, int t, byte[] m) - { - if (n < t) - { - throw new IllegalArgumentException("n < t"); - } - - BigInteger bc = IntegerFunctions.binomial(n, t); - // finds s = floor[log(binomial(n,t))] - int s = bc.bitLength() - 1; - // s = sq*8 + sr; - int sq = s >> 3; - int sr = s & 7; - if (sr == 0) - { - sq--; - sr = 8; - } - - // n = nq*8+nr; - int nq = n >> 3; - int nr = n & 7; - if (nr == 0) - { - nq--; - nr = 8; - } - // take s bit from m - byte[] data = new byte[nq + 1]; - if (m.length < data.length) - { - System.arraycopy(m, 0, data, 0, m.length); - for (int i = m.length; i < data.length; i++) - { - data[i] = 0; - } - } - else - { - System.arraycopy(m, 0, data, 0, nq); - int h = (1 << nr) - 1; - data[nq] = (byte)(h & m[nq]); - } - - BigInteger d = ZERO; - int nn = n; - int tt = t; - for (int i = 0; i < n; i++) - { - bc = (bc.multiply(new BigInteger(Integer.toString(nn - tt)))) - .divide(new BigInteger(Integer.toString(nn))); - nn--; - - int q = i >>> 3; - int r = i & 7; - r = 1 << r; - byte e = (byte)(r & data[q]); - if (e != 0) - { - d = d.add(bc); - tt--; - if (nn == tt) - { - bc = ONE; - } - else - { - bc = (bc - .multiply(new BigInteger(Integer.toString(tt + 1)))) - .divide(new BigInteger(Integer.toString(nn - tt))); - } - } - } - - byte[] result = new byte[sq + 1]; - byte[] help = d.toByteArray(); - if (help.length < result.length) - { - System.arraycopy(help, 0, result, 0, help.length); - for (int i = help.length; i < result.length; i++) - { - result[i] = 0; - } - } - else - { - System.arraycopy(help, 0, result, 0, sq); - result[sq] = (byte)(((1 << sr) - 1) & help[sq]); - } - - return result; - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.java deleted file mode 100644 index dbd5a82a..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyGenerationParameters.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.KeyGenerationParameters; - -public class McElieceCCA2KeyGenerationParameters - extends KeyGenerationParameters -{ - private McElieceCCA2Parameters params; - - public McElieceCCA2KeyGenerationParameters( - SecureRandom random, - McElieceCCA2Parameters params) - { - // XXX key size? - super(random, 128); - this.params = params; - } - - public McElieceCCA2Parameters getParameters() - { - return params; - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyPairGenerator.java deleted file mode 100644 index 198e5d29..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyPairGenerator.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; -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; -import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2m; - - -/** - * 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(new SecureRandom(), new McElieceCCA2Parameters()); - init(mcCCA2Params); - } - - // TODO - public void init( - KeyGenerationParameters param) - { - this.mcElieceCCA2Params = (McElieceCCA2KeyGenerationParameters)param; - - // set source of randomness - this.random = new SecureRandom(); - - 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); - PolynomialRingGF2m ring = new PolynomialRingGF2m(field, gp); - - // matrix for computing square roots in (GF(2^m))^t - PolynomialGF2mSmallM[] qInv = 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 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(OID, n, t, shortG, mcElieceCCA2Params.getParameters()); - McElieceCCA2PrivateKeyParameters privKey = new McElieceCCA2PrivateKeyParameters(OID, n, k, - field, gp, p, h, qInv, mcElieceCCA2Params.getParameters()); - - // return key pair - return new AsymmetricCipherKeyPair(pubKey, privKey); - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyParameters.java deleted file mode 100644 index 80114767..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2KeyParameters.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; - - -public class McElieceCCA2KeyParameters - extends AsymmetricKeyParameter -{ - private McElieceCCA2Parameters params; - - public McElieceCCA2KeyParameters( - boolean isPrivate, - McElieceCCA2Parameters params) - { - super(isPrivate); - this.params = params; - } - - - public McElieceCCA2Parameters getParameters() - { - return params; - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Parameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Parameters.java deleted file mode 100644 index 7f800106..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Parameters.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.digests.SHA256Digest; - -/** - * This class provides a specification for the parameters of the CCA2-secure - * variants of the McEliece PKCS that are used with - * {@link McElieceFujisakiCipher}, {@link McElieceKobaraImaiCipher}, and - * {@link McEliecePointchevalCipher}. - * - * @see McElieceFujisakiCipher - * @see McElieceKobaraImaiCipher - * @see McEliecePointchevalCipher - */ -public class McElieceCCA2Parameters - extends McElieceParameters -{ - - - public Digest digest; - - - /** - * Construct the default parameters. - * The default message digest is SHA256. - */ - public McElieceCCA2Parameters() - { - this.digest = new SHA256Digest(); - } - - public McElieceCCA2Parameters(int m, int t) - { - super(m, t); - this.digest = new SHA256Digest(); - } - - public McElieceCCA2Parameters(Digest digest) - { - this.digest = digest; - } - - public Digest getDigest() - { - return this.digest; - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Primitives.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Primitives.java deleted file mode 100644 index 726add15..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2Primitives.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; -import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; -import org.bouncycastle.pqc.math.linearalgebra.GF2mField; -import org.bouncycastle.pqc.math.linearalgebra.GoppaCode; -import org.bouncycastle.pqc.math.linearalgebra.Permutation; -import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; -import org.bouncycastle.pqc.math.linearalgebra.Vector; - -/** - * Core operations for the CCA-secure variants of McEliece. - */ -public final class McElieceCCA2Primitives -{ - - /** - * Default constructor (private). - */ - private McElieceCCA2Primitives() - { - } - - /** - * The McEliece encryption primitive. - * - * @param pubKey the public key - * @param m the message vector - * @param z the error vector - * @return <tt>m*G + z</tt> - */ - - - public static GF2Vector encryptionPrimitive(McElieceCCA2PublicKeyParameters pubKey, - GF2Vector m, GF2Vector z) - { - - GF2Matrix matrixG = pubKey.getMatrixG(); - Vector mG = matrixG.leftMultiplyLeftCompactForm(m); - return (GF2Vector)mG.add(z); - } - - /** - * The McEliece decryption primitive. - * - * @param privKey the private key - * @param c the ciphertext vector <tt>c = m*G + z</tt> - * @return the message vector <tt>m</tt> and the error vector <tt>z</tt> - */ - public static GF2Vector[] decryptionPrimitive( - McElieceCCA2PrivateKeyParameters privKey, GF2Vector c) - { - - // obtain values from private key - int k = privKey.getK(); - Permutation p = privKey.getP(); - GF2mField field = privKey.getField(); - PolynomialGF2mSmallM gp = privKey.getGoppaPoly(); - GF2Matrix h = privKey.getH(); - PolynomialGF2mSmallM[] q = privKey.getQInv(); - - // compute inverse permutation P^-1 - Permutation pInv = p.computeInverse(); - - // multiply c with permutation P^-1 - GF2Vector cPInv = (GF2Vector)c.multiply(pInv); - - // compute syndrome of cP^-1 - GF2Vector syndVec = (GF2Vector)h.rightMultiply(cPInv); - - // decode syndrome - GF2Vector errors = GoppaCode.syndromeDecode(syndVec, field, gp, q); - GF2Vector mG = (GF2Vector)cPInv.add(errors); - - // multiply codeword and error vector with P - mG = (GF2Vector)mG.multiply(p); - errors = (GF2Vector)errors.multiply(p); - - // extract plaintext vector (last k columns of mG) - GF2Vector m = mG.extractRightVector(k); - - // return vectors - return new GF2Vector[]{m, errors}; - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.java deleted file mode 100644 index 980ecdc9..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PrivateKeyParameters.java +++ /dev/null @@ -1,172 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - - -import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; -import org.bouncycastle.pqc.math.linearalgebra.GF2mField; -import org.bouncycastle.pqc.math.linearalgebra.Permutation; -import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; - -/** - * - * - * - */ -public class McElieceCCA2PrivateKeyParameters - extends McElieceCCA2KeyParameters -{ - - // the OID of the algorithm - private String oid; - - // the length of the code - private int n; - - // the dimension of the code - private int k; - - // the finte field GF(2^m) - private GF2mField field; - - // the irreducible Goppa polynomial - private PolynomialGF2mSmallM goppaPoly; - - // the permutation - private Permutation p; - - // the canonical check matrix - private GF2Matrix h; - - // the matrix used to compute square roots in (GF(2^m))^t - private PolynomialGF2mSmallM[] qInv; - - /** - * Constructor. - * - * @param n the length of the code - * @param k the dimension of the code - * @param field the finite field <tt>GF(2<sup>m</sup>)</tt> - * @param gp the irreducible Goppa polynomial - * @param p the permutation - * @param h the canonical check matrix - * @param qInv the matrix used to compute square roots in - * <tt>(GF(2^m))^t</tt> - * @param params McElieceCCA2Parameters - */ - public McElieceCCA2PrivateKeyParameters(String oid, int n, int k, GF2mField field, - PolynomialGF2mSmallM gp, Permutation p, GF2Matrix h, - PolynomialGF2mSmallM[] qInv, McElieceCCA2Parameters params) - { - super(true, params); - this.oid = oid; - this.n = n; - this.k = k; - this.field = field; - this.goppaPoly = gp; - this.p = p; - this.h = h; - this.qInv = qInv; - } - - /** - * Constructor used by the {@link McElieceKeyFactory}. - * - * @param n the length of the code - * @param k the dimension of the code - * @param encFieldPoly the encoded field polynomial defining the finite field - * <tt>GF(2<sup>m</sup>)</tt> - * @param encGoppaPoly the encoded irreducible Goppa polynomial - * @param encP the encoded permutation - * @param encH the encoded canonical check matrix - * @param encQInv the encoded matrix used to compute square roots in - * <tt>(GF(2^m))^t</tt> - * @param params McElieceCCA2Parameters - */ - public McElieceCCA2PrivateKeyParameters(String oid, int n, int k, byte[] encFieldPoly, - byte[] encGoppaPoly, byte[] encP, byte[] encH, byte[][] encQInv, McElieceCCA2Parameters params) - { - super(true, params); - this.oid = oid; - this.n = n; - this.k = k; - field = new GF2mField(encFieldPoly); - goppaPoly = new PolynomialGF2mSmallM(field, encGoppaPoly); - p = new Permutation(encP); - h = new GF2Matrix(encH); - qInv = new PolynomialGF2mSmallM[encQInv.length]; - for (int i = 0; i < encQInv.length; i++) - { - qInv[i] = new PolynomialGF2mSmallM(field, encQInv[i]); - } - } - - /** - * @return the length of the code - */ - public int getN() - { - return n; - } - - /** - * @return the dimension of the code - */ - public int getK() - { - return k; - } - - /** - * @return the degree of the Goppa polynomial (error correcting capability) - */ - public int getT() - { - return goppaPoly.getDegree(); - } - - /** - * @return the finite field - */ - public GF2mField getField() - { - return field; - } - - /** - * @return the irreducible Goppa polynomial - */ - public PolynomialGF2mSmallM getGoppaPoly() - { - return goppaPoly; - } - - /** - * @return the permutation P - */ - public Permutation getP() - { - return p; - } - - /** - * @return the canonical check matrix H - */ - public GF2Matrix getH() - { - return h; - } - - /** - * @return the matrix used to compute square roots in <tt>(GF(2^m))^t</tt> - */ - public PolynomialGF2mSmallM[] getQInv() - { - return qInv; - } - - public String getOIDString() - { - return oid; - - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PublicKeyParameters.java deleted file mode 100644 index e63377c3..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceCCA2PublicKeyParameters.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; - -/** - * - * - * - */ -public class McElieceCCA2PublicKeyParameters - extends McElieceCCA2KeyParameters -{ - - // the OID of the algorithm - private String oid; - - // the length of the code - private int n; - - // the error correction capability of the code - private int t; - - // the generator matrix - private GF2Matrix matrixG; - - /** - * Constructor. - * - * @param n length of the code - * @param t error correction capability - * @param matrix generator matrix - * @param params McElieceCCA2Parameters - */ - public McElieceCCA2PublicKeyParameters(String oid, int n, int t, GF2Matrix matrix, McElieceCCA2Parameters params) - { - super(false, params); - this.oid = oid; - this.n = n; - this.t = t; - this.matrixG = new GF2Matrix(matrix); - } - - /** - * Constructor (used by {@link McElieceKeyFactory}). - * - * @param n length of the code - * @param t error correction capability of the code - * @param encMatrix encoded generator matrix - * @param params McElieceCCA2Parameters - */ - public McElieceCCA2PublicKeyParameters(String oid, int n, int t, byte[] encMatrix, McElieceCCA2Parameters params) - { - super(false, params); - this.oid = oid; - this.n = n; - this.t = t; - this.matrixG = new GF2Matrix(encMatrix); - } - - /** - * @return the length of the code - */ - public int getN() - { - return n; - } - - /** - * @return the error correction capability of the code - */ - public int getT() - { - return t; - } - - /** - * @return the generator matrix - */ - public GF2Matrix getMatrixG() - { - return matrixG; - } - - /** - * @return the dimension of the code - */ - public int getK() - { - return matrixG.getNumRows(); - } - - public String getOIDString() - { - return oid; - - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiCipher.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiCipher.java deleted file mode 100644 index c414540f..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiCipher.java +++ /dev/null @@ -1,218 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.prng.DigestRandomGenerator; -import org.bouncycastle.pqc.crypto.MessageEncryptor; -import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; -import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; - -/** - * This class implements the Fujisaki/Okamoto conversion of the McEliecePKCS. - * Fujisaki and Okamoto propose hybrid encryption that merges a symmetric - * encryption scheme which is secure in the find-guess model with an asymmetric - * one-way encryption scheme which is sufficiently probabilistic to obtain a - * public key cryptosystem which is CCA2-secure. For details, see D. Engelbert, - * R. Overbeck, A. Schmidt, "A summary of the development of the McEliece - * Cryptosystem", technical report. - */ -public class McElieceFujisakiCipher - implements MessageEncryptor -{ - - - /** - * The OID of the algorithm. - */ - public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.1"; - - private static final String DEFAULT_PRNG_NAME = "SHA1PRNG"; - - private Digest messDigest; - - private SecureRandom sr; - - /** - * The McEliece main parameters - */ - private int n, k, t; - - McElieceCCA2KeyParameters key; - - - public void init(boolean forSigning, - CipherParameters param) - { - - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.sr = rParam.getRandom(); - this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters(); - this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); - - } - else - { - this.sr = new SecureRandom(); - this.key = (McElieceCCA2PublicKeyParameters)param; - this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); - } - } - else - { - this.key = (McElieceCCA2PrivateKeyParameters)param; - this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key); - } - - } - - - public int getKeySize(McElieceCCA2KeyParameters key) - throws IllegalArgumentException - { - - if (key instanceof McElieceCCA2PublicKeyParameters) - { - return ((McElieceCCA2PublicKeyParameters)key).getN(); - - } - if (key instanceof McElieceCCA2PrivateKeyParameters) - { - return ((McElieceCCA2PrivateKeyParameters)key).getN(); - } - throw new IllegalArgumentException("unsupported type"); - - } - - - private void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey) - { - this.sr = sr != null ? sr : new SecureRandom(); - this.messDigest = pubKey.getParameters().getDigest(); - n = pubKey.getN(); - k = pubKey.getK(); - t = pubKey.getT(); - } - - - public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey) - { - this.messDigest = privKey.getParameters().getDigest(); - n = privKey.getN(); - t = privKey.getT(); - } - - - public byte[] messageEncrypt(byte[] input) - throws Exception - { - - // generate random vector r of length k bits - GF2Vector r = new GF2Vector(k, sr); - - // convert r to byte array - byte[] rBytes = r.getEncoded(); - - // compute (r||input) - byte[] rm = ByteUtils.concatenate(rBytes, input); - - // compute H(r||input) - messDigest.update(rm, 0, rm.length); - byte[] hrm = new byte[messDigest.getDigestSize()]; - messDigest.doFinal(hrm, 0); - - // convert H(r||input) to error vector z - GF2Vector z = Conversions.encode(n, t, hrm); - - // compute c1 = E(r, z) - byte[] c1 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key, r, z) - .getEncoded(); - - // get PRNG object - DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); - - // seed PRNG with r' - sr0.addSeedMaterial(rBytes); - - // generate random c2 - byte[] c2 = new byte[input.length]; - sr0.nextBytes(c2); - - // XOR with input - for (int i = 0; i < input.length; i++) - { - c2[i] ^= input[i]; - } - - // return (c1||c2) - return ByteUtils.concatenate(c1, c2); - } - - public byte[] messageDecrypt(byte[] input) - throws Exception - { - - int c1Len = (n + 7) >> 3; - int c2Len = input.length - c1Len; - - // split ciphertext (c1||c2) - byte[][] c1c2 = ByteUtils.split(input, c1Len); - byte[] c1 = c1c2[0]; - byte[] c2 = c1c2[1]; - - // decrypt c1 ... - GF2Vector hrmVec = GF2Vector.OS2VP(n, c1); - GF2Vector[] decC1 = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key, - hrmVec); - byte[] rBytes = decC1[0].getEncoded(); - // ... and obtain error vector z - GF2Vector z = decC1[1]; - - // get PRNG object - DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); - - // seed PRNG with r' - sr0.addSeedMaterial(rBytes); - - // generate random sequence - byte[] mBytes = new byte[c2Len]; - sr0.nextBytes(mBytes); - - // XOR with c2 to obtain m - for (int i = 0; i < c2Len; i++) - { - mBytes[i] ^= c2[i]; - } - - // compute H(r||m) - byte[] rmBytes = ByteUtils.concatenate(rBytes, mBytes); - byte[] hrm = new byte[messDigest.getDigestSize()]; - messDigest.update(rmBytes, 0, rmBytes.length); - messDigest.doFinal(hrm, 0); - - - // compute Conv(H(r||m)) - hrmVec = Conversions.encode(n, t, hrm); - - // check that Conv(H(m||r)) = z - if (!hrmVec.equals(z)) - { - - throw new Exception("Bad Padding: invalid ciphertext"); - - } - - // return plaintext m - return mBytes; - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiDigestCipher.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiDigestCipher.java deleted file mode 100644 index 423e6ff8..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceFujisakiDigestCipher.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.pqc.crypto.MessageEncryptor; - -// TODO should implement some interface? -public class McElieceFujisakiDigestCipher -{ - - private final Digest messDigest; - - private final MessageEncryptor mcElieceCCA2Cipher; - - private boolean forEncrypting; - - - public McElieceFujisakiDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest) - { - this.mcElieceCCA2Cipher = mcElieceCCA2Cipher; - this.messDigest = messDigest; - } - - - public void init(boolean forEncrypting, - CipherParameters param) - { - - this.forEncrypting = forEncrypting; - AsymmetricKeyParameter k; - - if (param instanceof ParametersWithRandom) - { - k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); - } - else - { - k = (AsymmetricKeyParameter)param; - } - - if (forEncrypting && k.isPrivate()) - { - throw new IllegalArgumentException("Encrypting Requires Public Key."); - } - - if (!forEncrypting && !k.isPrivate()) - { - throw new IllegalArgumentException("Decrypting Requires Private Key."); - } - - reset(); - - mcElieceCCA2Cipher.init(forEncrypting, param); - } - - - public byte[] messageEncrypt() - { - if (!forEncrypting) - { - throw new IllegalStateException("McElieceFujisakiDigestCipher not initialised for encrypting."); - } - - byte[] hash = new byte[messDigest.getDigestSize()]; - messDigest.doFinal(hash, 0); - byte[] enc = null; - - try - { - enc = mcElieceCCA2Cipher.messageEncrypt(hash); - } - catch (Exception e) - { - e.printStackTrace(); - } - - - return enc; - } - - - public byte[] messageDecrypt(byte[] ciphertext) - { - byte[] output = null; - if (forEncrypting) - { - throw new IllegalStateException("McElieceFujisakiDigestCipher not initialised for decrypting."); - } - - - try - { - output = mcElieceCCA2Cipher.messageDecrypt(ciphertext); - } - catch (Exception e) - { - e.printStackTrace(); - } - - - return output; - } - - - public void update(byte b) - { - messDigest.update(b); - - } - - public void update(byte[] in, int off, int len) - { - messDigest.update(in, off, len); - - } - - - public void reset() - { - messDigest.reset(); - - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyGenerationParameters.java deleted file mode 100644 index 1b1fa658..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyGenerationParameters.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.KeyGenerationParameters; - -public class McElieceKeyGenerationParameters - extends KeyGenerationParameters -{ - private McElieceParameters params; - - public McElieceKeyGenerationParameters( - SecureRandom random, - McElieceParameters params) - { - // XXX key size? - super(random, 256); - this.params = params; - } - - public McElieceParameters getParameters() - { - return params; - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java deleted file mode 100644 index 6ad7fc2f..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyPairGenerator.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; -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; -import org.bouncycastle.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(); - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyParameters.java deleted file mode 100644 index 007e743e..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKeyParameters.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; - - -public class McElieceKeyParameters - extends AsymmetricKeyParameter -{ - private McElieceParameters params; - - public McElieceKeyParameters( - boolean isPrivate, - McElieceParameters params) - { - super(isPrivate); - this.params = params; - } - - - public McElieceParameters getParameters() - { - return params; - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiCipher.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiCipher.java deleted file mode 100644 index fe3ebf94..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiCipher.java +++ /dev/null @@ -1,319 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.prng.DigestRandomGenerator; -import org.bouncycastle.pqc.crypto.MessageEncryptor; -import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; -import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; -import org.bouncycastle.pqc.math.linearalgebra.IntegerFunctions; - -/** - * This class implements the Kobara/Imai conversion of the McEliecePKCS. This is - * a conversion of the McEliecePKCS which is CCA2-secure. For details, see D. - * Engelbert, R. Overbeck, A. Schmidt, "A summary of the development of the - * McEliece Cryptosystem", technical report. - */ -public class McElieceKobaraImaiCipher - implements MessageEncryptor -{ - - /** - * The OID of the algorithm. - */ - public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.3"; - - private static final String DEFAULT_PRNG_NAME = "SHA1PRNG"; - - /** - * A predetermined public constant. - */ - public static final byte[] PUBLIC_CONSTANT = "a predetermined public constant" - .getBytes(); - - - private Digest messDigest; - - private SecureRandom sr; - - McElieceCCA2KeyParameters key; - - /** - * The McEliece main parameters - */ - private int n, k, t; - - - public void init(boolean forSigning, - CipherParameters param) - { - - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.sr = rParam.getRandom(); - this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters(); - this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); - - } - else - { - this.sr = new SecureRandom(); - this.key = (McElieceCCA2PublicKeyParameters)param; - this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); - } - } - else - { - this.key = (McElieceCCA2PrivateKeyParameters)param; - this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key); - } - - } - - /** - * Return the key size of the given key object. - * - * @param key the McElieceCCA2KeyParameters object - * @return the key size of the given key object - */ - public int getKeySize(McElieceCCA2KeyParameters key) - { - if (key instanceof McElieceCCA2PublicKeyParameters) - { - return ((McElieceCCA2PublicKeyParameters)key).getN(); - - } - if (key instanceof McElieceCCA2PrivateKeyParameters) - { - return ((McElieceCCA2PrivateKeyParameters)key).getN(); - } - throw new IllegalArgumentException("unsupported type"); - } - - private void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey) - { - this.messDigest = pubKey.getParameters().getDigest(); - n = pubKey.getN(); - k = pubKey.getK(); - t = pubKey.getT(); - - } - - public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey) - { - this.messDigest = privKey.getParameters().getDigest(); - n = privKey.getN(); - k = privKey.getK(); - t = privKey.getT(); - } - - public byte[] messageEncrypt(byte[] input) - throws Exception - { - - int c2Len = messDigest.getDigestSize(); - int c4Len = k >> 3; - int c5Len = (IntegerFunctions.binomial(n, t).bitLength() - 1) >> 3; - - - int mLen = c4Len + c5Len - c2Len - PUBLIC_CONSTANT.length; - if (input.length > mLen) - { - mLen = input.length; - } - - int c1Len = mLen + PUBLIC_CONSTANT.length; - int c6Len = c1Len + c2Len - c4Len - c5Len; - - // compute (m||const) - byte[] mConst = new byte[c1Len]; - System.arraycopy(input, 0, mConst, 0, input.length); - System.arraycopy(PUBLIC_CONSTANT, 0, mConst, mLen, - PUBLIC_CONSTANT.length); - - // generate random r of length c2Len bytes - byte[] r = new byte[c2Len]; - sr.nextBytes(r); - - // get PRNG object - // get PRNG object - DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); - - // seed PRNG with r' - sr0.addSeedMaterial(r); - - // generate random sequence ... - byte[] c1 = new byte[c1Len]; - sr0.nextBytes(c1); - - // ... and XOR with (m||const) to obtain c1 - for (int i = c1Len - 1; i >= 0; i--) - { - c1[i] ^= mConst[i]; - } - - // compute H(c1) ... - byte[] c2 = new byte[messDigest.getDigestSize()]; - messDigest.update(c1, 0, c1.length); - messDigest.doFinal(c2, 0); - - // ... and XOR with r - for (int i = c2Len - 1; i >= 0; i--) - { - c2[i] ^= r[i]; - } - - // compute (c2||c1) - byte[] c2c1 = ByteUtils.concatenate(c2, c1); - - // split (c2||c1) into (c6||c5||c4), where c4Len is k/8 bytes, c5Len is - // floor[log(n|t)]/8 bytes, and c6Len is c1Len+c2Len-c4Len-c5Len (may be - // 0). - byte[] c6 = new byte[0]; - if (c6Len > 0) - { - c6 = new byte[c6Len]; - System.arraycopy(c2c1, 0, c6, 0, c6Len); - } - - byte[] c5 = new byte[c5Len]; - System.arraycopy(c2c1, c6Len, c5, 0, c5Len); - - byte[] c4 = new byte[c4Len]; - System.arraycopy(c2c1, c6Len + c5Len, c4, 0, c4Len); - - // convert c4 to vector over GF(2) - GF2Vector c4Vec = GF2Vector.OS2VP(k, c4); - - // convert c5 to error vector z - GF2Vector z = Conversions.encode(n, t, c5); - - // compute encC4 = E(c4, z) - byte[] encC4 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key, - c4Vec, z).getEncoded(); - - // if c6Len > 0 - if (c6Len > 0) - { - // return (c6||encC4) - return ByteUtils.concatenate(c6, encC4); - } - // else, return encC4 - return encC4; - } - - - public byte[] messageDecrypt(byte[] input) - throws Exception - { - - int nDiv8 = n >> 3; - - if (input.length < nDiv8) - { - throw new Exception("Bad Padding: Ciphertext too short."); - } - - int c2Len = messDigest.getDigestSize(); - int c4Len = k >> 3; - int c6Len = input.length - nDiv8; - - // split cipher text (c6||encC4), where c6 may be empty - byte[] c6, encC4; - if (c6Len > 0) - { - byte[][] c6EncC4 = ByteUtils.split(input, c6Len); - c6 = c6EncC4[0]; - encC4 = c6EncC4[1]; - } - else - { - c6 = new byte[0]; - encC4 = input; - } - - // convert encC4 into vector over GF(2) - GF2Vector encC4Vec = GF2Vector.OS2VP(n, encC4); - - // decrypt encC4Vec to obtain c4 and error vector z - GF2Vector[] c4z = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key, - encC4Vec); - byte[] c4 = c4z[0].getEncoded(); - GF2Vector z = c4z[1]; - - // if length of c4 is greater than c4Len (because of padding) ... - if (c4.length > c4Len) - { - // ... truncate the padding bytes - c4 = ByteUtils.subArray(c4, 0, c4Len); - } - - // compute c5 = Conv^-1(z) - byte[] c5 = Conversions.decode(n, t, z); - - // compute (c6||c5||c4) - byte[] c6c5c4 = ByteUtils.concatenate(c6, c5); - c6c5c4 = ByteUtils.concatenate(c6c5c4, c4); - - // split (c6||c5||c4) into (c2||c1), where c2Len = mdLen and c1Len = - // input.length-c2Len bytes. - int c1Len = c6c5c4.length - c2Len; - byte[][] c2c1 = ByteUtils.split(c6c5c4, c2Len); - byte[] c2 = c2c1[0]; - byte[] c1 = c2c1[1]; - - // compute H(c1) ... - byte[] rPrime = new byte[messDigest.getDigestSize()]; - messDigest.update(c1, 0, c1.length); - messDigest.doFinal(rPrime, 0); - - // ... and XOR with c2 to obtain r' - for (int i = c2Len - 1; i >= 0; i--) - { - rPrime[i] ^= c2[i]; - } - - // get PRNG object - DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); - - // seed PRNG with r' - sr0.addSeedMaterial(rPrime); - - // generate random sequence R(r') ... - byte[] mConstPrime = new byte[c1Len]; - sr0.nextBytes(mConstPrime); - - // ... and XOR with c1 to obtain (m||const') - for (int i = c1Len - 1; i >= 0; i--) - { - mConstPrime[i] ^= c1[i]; - } - - if (mConstPrime.length < c1Len) - { - throw new Exception("Bad Padding: invalid ciphertext"); - } - - byte[][] temp = ByteUtils.split(mConstPrime, c1Len - - PUBLIC_CONSTANT.length); - byte[] mr = temp[0]; - byte[] constPrime = temp[1]; - - if (!ByteUtils.equals(constPrime, PUBLIC_CONSTANT)) - { - throw new Exception("Bad Padding: invalid ciphertext"); - } - - return mr; - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiDigestCipher.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiDigestCipher.java deleted file mode 100644 index 365f387c..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceKobaraImaiDigestCipher.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.pqc.crypto.MessageEncryptor; - -// TODO should implement some interface? -public class McElieceKobaraImaiDigestCipher -{ - - private final Digest messDigest; - - private final MessageEncryptor mcElieceCCA2Cipher; - - private boolean forEncrypting; - - - public McElieceKobaraImaiDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest) - { - this.mcElieceCCA2Cipher = mcElieceCCA2Cipher; - this.messDigest = messDigest; - } - - - public void init(boolean forEncrypting, - CipherParameters param) - { - - this.forEncrypting = forEncrypting; - AsymmetricKeyParameter k; - - if (param instanceof ParametersWithRandom) - { - k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); - } - else - { - k = (AsymmetricKeyParameter)param; - } - - if (forEncrypting && k.isPrivate()) - { - throw new IllegalArgumentException("Encrypting Requires Public Key."); - } - - if (!forEncrypting && !k.isPrivate()) - { - throw new IllegalArgumentException("Decrypting Requires Private Key."); - } - - reset(); - - mcElieceCCA2Cipher.init(forEncrypting, param); - } - - - public byte[] messageEncrypt() - { - if (!forEncrypting) - { - throw new IllegalStateException("McElieceKobaraImaiDigestCipher not initialised for encrypting."); - } - - byte[] hash = new byte[messDigest.getDigestSize()]; - messDigest.doFinal(hash, 0); - byte[] enc = null; - - try - { - enc = mcElieceCCA2Cipher.messageEncrypt(hash); - } - catch (Exception e) - { - e.printStackTrace(); - } - - - return enc; - } - - - public byte[] messageDecrypt(byte[] ciphertext) - { - byte[] output = null; - if (forEncrypting) - { - throw new IllegalStateException("McElieceKobaraImaiDigestCipher not initialised for decrypting."); - } - - - try - { - output = mcElieceCCA2Cipher.messageDecrypt(ciphertext); - } - catch (Exception e) - { - e.printStackTrace(); - } - - - return output; - } - - - public void update(byte b) - { - messDigest.update(b); - - } - - public void update(byte[] in, int off, int len) - { - messDigest.update(in, off, len); - - } - - - public void reset() - { - messDigest.reset(); - - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSCipher.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSCipher.java deleted file mode 100644 index 7a6be1be..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSCipher.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.pqc.crypto.MessageEncryptor; -import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; -import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; -import org.bouncycastle.pqc.math.linearalgebra.GF2mField; -import org.bouncycastle.pqc.math.linearalgebra.GoppaCode; -import org.bouncycastle.pqc.math.linearalgebra.Permutation; -import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; -import org.bouncycastle.pqc.math.linearalgebra.Vector; - -/** - * This class implements the McEliece Public Key cryptosystem (McEliecePKCS). It - * was first described in R.J. McEliece, "A public key cryptosystem based on - * algebraic coding theory", DSN progress report, 42-44:114-116, 1978. The - * McEliecePKCS is the first cryptosystem which is based on error correcting - * codes. The trapdoor for the McEliece cryptosystem using Goppa codes is the - * knowledge of the Goppa polynomial used to generate the code. - */ -public class McEliecePKCSCipher - implements MessageEncryptor -{ - - /** - * The OID of the algorithm. - */ - public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.1"; - - - // the source of randomness - private SecureRandom sr; - - // the McEliece main parameters - private int n, k, t; - - // The maximum number of bytes the cipher can decrypt - public int maxPlainTextSize; - - // The maximum number of bytes the cipher can encrypt - public int cipherTextSize; - - McElieceKeyParameters key; - - - public void init(boolean forSigning, - CipherParameters param) - { - - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.sr = rParam.getRandom(); - this.key = (McEliecePublicKeyParameters)rParam.getParameters(); - this.initCipherEncrypt((McEliecePublicKeyParameters)key); - - } - else - { - this.sr = new SecureRandom(); - this.key = (McEliecePublicKeyParameters)param; - this.initCipherEncrypt((McEliecePublicKeyParameters)key); - } - } - else - { - this.key = (McEliecePrivateKeyParameters)param; - this.initCipherDecrypt((McEliecePrivateKeyParameters)key); - } - - } - - - /** - * Return the key size of the given key object. - * - * @param key the McElieceKeyParameters object - * @return the keysize of the given key object - */ - - public int getKeySize(McElieceKeyParameters key) - { - - if (key instanceof McEliecePublicKeyParameters) - { - return ((McEliecePublicKeyParameters)key).getN(); - - } - if (key instanceof McEliecePrivateKeyParameters) - { - return ((McEliecePrivateKeyParameters)key).getN(); - } - throw new IllegalArgumentException("unsupported type"); - - } - - - public void initCipherEncrypt(McEliecePublicKeyParameters pubKey) - { - this.sr = sr != null ? sr : new SecureRandom(); - n = pubKey.getN(); - k = pubKey.getK(); - t = pubKey.getT(); - cipherTextSize = n >> 3; - maxPlainTextSize = (k >> 3); - } - - - public void initCipherDecrypt(McEliecePrivateKeyParameters privKey) - { - n = privKey.getN(); - k = privKey.getK(); - - maxPlainTextSize = (k >> 3); - cipherTextSize = n >> 3; - } - - /** - * Encrypt a plain text. - * - * @param input the plain text - * @return the cipher text - */ - public byte[] messageEncrypt(byte[] input) - { - GF2Vector m = computeMessageRepresentative(input); - GF2Vector z = new GF2Vector(n, t, sr); - - GF2Matrix g = ((McEliecePublicKeyParameters)key).getG(); - Vector mG = g.leftMultiply(m); - GF2Vector mGZ = (GF2Vector)mG.add(z); - - return mGZ.getEncoded(); - } - - private GF2Vector computeMessageRepresentative(byte[] input) - { - byte[] data = new byte[maxPlainTextSize + ((k & 0x07) != 0 ? 1 : 0)]; - System.arraycopy(input, 0, data, 0, input.length); - data[input.length] = 0x01; - return GF2Vector.OS2VP(k, data); - } - - /** - * Decrypt a cipher text. - * - * @param input the cipher text - * @return the plain text - * @throws Exception if the cipher text is invalid. - */ - public byte[] messageDecrypt(byte[] input) - throws Exception - { - GF2Vector vec = GF2Vector.OS2VP(n, input); - McEliecePrivateKeyParameters privKey = (McEliecePrivateKeyParameters)key; - GF2mField field = privKey.getField(); - PolynomialGF2mSmallM gp = privKey.getGoppaPoly(); - GF2Matrix sInv = privKey.getSInv(); - Permutation p1 = privKey.getP1(); - Permutation p2 = privKey.getP2(); - GF2Matrix h = privKey.getH(); - PolynomialGF2mSmallM[] qInv = privKey.getQInv(); - - // compute permutation P = P1 * P2 - Permutation p = p1.rightMultiply(p2); - - // compute P^-1 - Permutation pInv = p.computeInverse(); - - // compute c P^-1 - GF2Vector cPInv = (GF2Vector)vec.multiply(pInv); - - // compute syndrome of c P^-1 - GF2Vector syndrome = (GF2Vector)h.rightMultiply(cPInv); - - // decode syndrome - GF2Vector z = GoppaCode.syndromeDecode(syndrome, field, gp, qInv); - GF2Vector mSG = (GF2Vector)cPInv.add(z); - - // multiply codeword with P1 and error vector with P - mSG = (GF2Vector)mSG.multiply(p1); - z = (GF2Vector)z.multiply(p); - - // extract mS (last k columns of mSG) - GF2Vector mS = mSG.extractRightVector(k); - - // compute plaintext vector - GF2Vector mVec = (GF2Vector)sInv.leftMultiply(mS); - - // compute and return plaintext - return computeMessage(mVec); - } - - private byte[] computeMessage(GF2Vector mr) - throws Exception - { - byte[] mrBytes = mr.getEncoded(); - // find first non-zero byte - int index; - for (index = mrBytes.length - 1; index >= 0 && mrBytes[index] == 0; index--) - { - ; - } - - // check if padding byte is valid - if (mrBytes[index] != 0x01) - { - throw new Exception("Bad Padding: invalid ciphertext"); - } - - // extract and return message - byte[] mBytes = new byte[index]; - System.arraycopy(mrBytes, 0, mBytes, 0, index); - return mBytes; - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSDigestCipher.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSDigestCipher.java deleted file mode 100644 index d8e6ba25..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePKCSDigestCipher.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.pqc.crypto.MessageEncryptor; - -// TODO should implement some interface? -public class McEliecePKCSDigestCipher -{ - - private final Digest messDigest; - - private final MessageEncryptor mcElieceCipher; - - private boolean forEncrypting; - - - public McEliecePKCSDigestCipher(MessageEncryptor mcElieceCipher, Digest messDigest) - { - this.mcElieceCipher = mcElieceCipher; - this.messDigest = messDigest; - } - - - public void init(boolean forEncrypting, - CipherParameters param) - { - - this.forEncrypting = forEncrypting; - AsymmetricKeyParameter k; - - if (param instanceof ParametersWithRandom) - { - k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); - } - else - { - k = (AsymmetricKeyParameter)param; - } - - if (forEncrypting && k.isPrivate()) - { - throw new IllegalArgumentException("Encrypting Requires Public Key."); - } - - if (!forEncrypting && !k.isPrivate()) - { - throw new IllegalArgumentException("Decrypting Requires Private Key."); - } - - reset(); - - mcElieceCipher.init(forEncrypting, param); - } - - - public byte[] messageEncrypt() - { - if (!forEncrypting) - { - throw new IllegalStateException("McEliecePKCSDigestCipher not initialised for encrypting."); - } - - byte[] hash = new byte[messDigest.getDigestSize()]; - messDigest.doFinal(hash, 0); - byte[] enc = null; - - try - { - enc = mcElieceCipher.messageEncrypt(hash); - } - catch (Exception e) - { - e.printStackTrace(); - } - - - return enc; - } - - - public byte[] messageDecrypt(byte[] ciphertext) - { - byte[] output = null; - if (forEncrypting) - { - throw new IllegalStateException("McEliecePKCSDigestCipher not initialised for decrypting."); - } - - - try - { - output = mcElieceCipher.messageDecrypt(ciphertext); - } - catch (Exception e) - { - e.printStackTrace(); - } - - - return output; - } - - - public void update(byte b) - { - messDigest.update(b); - - } - - public void update(byte[] in, int off, int len) - { - messDigest.update(in, off, len); - - } - - - public void reset() - { - messDigest.reset(); - - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceParameters.java deleted file mode 100644 index e90c7846..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McElieceParameters.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2; - -public class McElieceParameters - implements CipherParameters -{ - - /** - * The default extension degree - */ - public static final int DEFAULT_M = 11; - - /** - * The default error correcting capability. - */ - public static final int DEFAULT_T = 50; - - /** - * extension degree of the finite field GF(2^m) - */ - private int m; - - /** - * error correction capability of the code - */ - private int t; - - /** - * length of the code - */ - private int n; - - /** - * the field polynomial - */ - private int fieldPoly; - - /** - * Constructor. Set the default parameters: extension degree. - */ - public McElieceParameters() - { - this(DEFAULT_M, DEFAULT_T); - } - - /** - * Constructor. - * - * @param keysize the length of a Goppa code - * @throws IllegalArgumentException if <tt>keysize < 1</tt>. - */ - public McElieceParameters(int keysize) - throws IllegalArgumentException - { - if (keysize < 1) - { - throw new IllegalArgumentException("key size must be positive"); - } - m = 0; - n = 1; - while (n < keysize) - { - n <<= 1; - m++; - } - t = n >>> 1; - t /= m; - fieldPoly = PolynomialRingGF2.getIrreduciblePolynomial(m); - } - - /** - * Constructor. - * - * @param m degree of the finite field GF(2^m) - * @param t error correction capability of the code - * @throws IllegalArgumentException if <tt>m < 1</tt> or <tt>m > 32</tt> or - * <tt>t < 0</tt> or <tt>t > n</tt>. - */ - public McElieceParameters(int m, int t) - throws IllegalArgumentException - { - if (m < 1) - { - throw new IllegalArgumentException("m must be positive"); - } - if (m > 32) - { - throw new IllegalArgumentException("m is too large"); - } - this.m = m; - n = 1 << m; - if (t < 0) - { - throw new IllegalArgumentException("t must be positive"); - } - if (t > n) - { - throw new IllegalArgumentException("t must be less than n = 2^m"); - } - this.t = t; - fieldPoly = PolynomialRingGF2.getIrreduciblePolynomial(m); - } - - /** - * Constructor. - * - * @param m degree of the finite field GF(2^m) - * @param t error correction capability of the code - * @param poly the field polynomial - * @throws IllegalArgumentException if <tt>m < 1</tt> or <tt>m > 32</tt> or - * <tt>t < 0</tt> or <tt>t > n</tt> or - * <tt>poly</tt> is not an irreducible field polynomial. - */ - public McElieceParameters(int m, int t, int poly) - throws IllegalArgumentException - { - this.m = m; - if (m < 1) - { - throw new IllegalArgumentException("m must be positive"); - } - if (m > 32) - { - throw new IllegalArgumentException(" m is too large"); - } - this.n = 1 << m; - this.t = t; - if (t < 0) - { - throw new IllegalArgumentException("t must be positive"); - } - if (t > n) - { - throw new IllegalArgumentException("t must be less than n = 2^m"); - } - if ((PolynomialRingGF2.degree(poly) == m) - && (PolynomialRingGF2.isIrreducible(poly))) - { - this.fieldPoly = poly; - } - else - { - throw new IllegalArgumentException( - "polynomial is not a field polynomial for GF(2^m)"); - } - } - - /** - * @return the extension degree of the finite field GF(2^m) - */ - public int getM() - { - return m; - } - - /** - * @return the length of the code - */ - public int getN() - { - return n; - } - - /** - * @return the error correction capability of the code - */ - public int getT() - { - return t; - } - - /** - * @return the field polynomial - */ - public int getFieldPoly() - { - return fieldPoly; - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalCipher.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalCipher.java deleted file mode 100644 index 854d79e0..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalCipher.java +++ /dev/null @@ -1,241 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.prng.DigestRandomGenerator; -import org.bouncycastle.pqc.crypto.MessageEncryptor; -import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; -import org.bouncycastle.pqc.math.linearalgebra.GF2Vector; - -/** - * This class implements the Pointcheval conversion of the McEliecePKCS. - * Pointcheval presents a generic technique to make a CCA2-secure cryptosystem - * from any partially trapdoor one-way function in the random oracle model. For - * details, see D. Engelbert, R. Overbeck, A. Schmidt, "A summary of the - * development of the McEliece Cryptosystem", technical report. - */ -public class McEliecePointchevalCipher - implements MessageEncryptor -{ - - - /** - * The OID of the algorithm. - */ - public static final String OID = "1.3.6.1.4.1.8301.3.1.3.4.2.2"; - - private Digest messDigest; - - private SecureRandom sr; - - /** - * The McEliece main parameters - */ - private int n, k, t; - - McElieceCCA2KeyParameters key; - - public void init(boolean forSigning, - CipherParameters param) - { - - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.sr = rParam.getRandom(); - this.key = (McElieceCCA2PublicKeyParameters)rParam.getParameters(); - this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); - - } - else - { - this.sr = new SecureRandom(); - this.key = (McElieceCCA2PublicKeyParameters)param; - this.initCipherEncrypt((McElieceCCA2PublicKeyParameters)key); - } - } - else - { - this.key = (McElieceCCA2PrivateKeyParameters)param; - this.initCipherDecrypt((McElieceCCA2PrivateKeyParameters)key); - } - - } - - /** - * Return the key size of the given key object. - * - * @param key the McElieceCCA2KeyParameters object - * @return the key size of the given key object - * @throws IllegalArgumentException if the key is invalid - */ - public int getKeySize(McElieceCCA2KeyParameters key) - throws IllegalArgumentException - { - - if (key instanceof McElieceCCA2PublicKeyParameters) - { - return ((McElieceCCA2PublicKeyParameters)key).getN(); - - } - if (key instanceof McElieceCCA2PrivateKeyParameters) - { - return ((McElieceCCA2PrivateKeyParameters)key).getN(); - } - throw new IllegalArgumentException("unsupported type"); - - } - - - protected int decryptOutputSize(int inLen) - { - return 0; - } - - protected int encryptOutputSize(int inLen) - { - return 0; - } - - - public void initCipherEncrypt(McElieceCCA2PublicKeyParameters pubKey) - { - this.sr = sr != null ? sr : new SecureRandom(); - this.messDigest = pubKey.getParameters().getDigest(); - n = pubKey.getN(); - k = pubKey.getK(); - t = pubKey.getT(); - } - - public void initCipherDecrypt(McElieceCCA2PrivateKeyParameters privKey) - { - this.messDigest = privKey.getParameters().getDigest(); - n = privKey.getN(); - k = privKey.getK(); - t = privKey.getT(); - } - - public byte[] messageEncrypt(byte[] input) - throws Exception - { - - int kDiv8 = k >> 3; - - // generate random r of length k div 8 bytes - byte[] r = new byte[kDiv8]; - sr.nextBytes(r); - - // generate random vector r' of length k bits - GF2Vector rPrime = new GF2Vector(k, sr); - - // convert r' to byte array - byte[] rPrimeBytes = rPrime.getEncoded(); - - // compute (input||r) - byte[] mr = ByteUtils.concatenate(input, r); - - // compute H(input||r) - messDigest.update(mr, 0, mr.length); - byte[] hmr = new byte[messDigest.getDigestSize()]; - messDigest.doFinal(hmr, 0); - - - // convert H(input||r) to error vector z - GF2Vector z = Conversions.encode(n, t, hmr); - - // compute c1 = E(rPrime, z) - byte[] c1 = McElieceCCA2Primitives.encryptionPrimitive((McElieceCCA2PublicKeyParameters)key, rPrime, - z).getEncoded(); - - // get PRNG object - DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); - - // seed PRNG with r' - sr0.addSeedMaterial(rPrimeBytes); - - // generate random c2 - byte[] c2 = new byte[input.length + kDiv8]; - sr0.nextBytes(c2); - - // XOR with input - for (int i = 0; i < input.length; i++) - { - c2[i] ^= input[i]; - } - // XOR with r - for (int i = 0; i < kDiv8; i++) - { - c2[input.length + i] ^= r[i]; - } - - // return (c1||c2) - return ByteUtils.concatenate(c1, c2); - } - - public byte[] messageDecrypt(byte[] input) - throws Exception - { - - int c1Len = (n + 7) >> 3; - int c2Len = input.length - c1Len; - - // split cipher text (c1||c2) - byte[][] c1c2 = ByteUtils.split(input, c1Len); - byte[] c1 = c1c2[0]; - byte[] c2 = c1c2[1]; - - // decrypt c1 ... - GF2Vector c1Vec = GF2Vector.OS2VP(n, c1); - GF2Vector[] c1Dec = McElieceCCA2Primitives.decryptionPrimitive((McElieceCCA2PrivateKeyParameters)key, - c1Vec); - byte[] rPrimeBytes = c1Dec[0].getEncoded(); - // ... and obtain error vector z - GF2Vector z = c1Dec[1]; - - // get PRNG object - DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); - - // seed PRNG with r' - sr0.addSeedMaterial(rPrimeBytes); - - // generate random sequence - byte[] mrBytes = new byte[c2Len]; - sr0.nextBytes(mrBytes); - - // XOR with c2 to obtain (m||r) - for (int i = 0; i < c2Len; i++) - { - mrBytes[i] ^= c2[i]; - } - - // compute H(m||r) - messDigest.update(mrBytes, 0, mrBytes.length); - byte[] hmr = new byte[messDigest.getDigestSize()]; - messDigest.doFinal(hmr, 0); - - // compute Conv(H(m||r)) - c1Vec = Conversions.encode(n, t, hmr); - - // check that Conv(H(m||r)) = z - if (!c1Vec.equals(z)) - { - throw new Exception("Bad Padding: Invalid ciphertext."); - } - - // split (m||r) to obtain m - int kDiv8 = k >> 3; - byte[][] mr = ByteUtils.split(mrBytes, c2Len - kDiv8); - - // return plain text m - return mr[0]; - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalDigestCipher.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalDigestCipher.java deleted file mode 100644 index 8a1ed62a..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePointchevalDigestCipher.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.pqc.crypto.MessageEncryptor; - -// TODO should implement some interface? -public class McEliecePointchevalDigestCipher -{ - - private final Digest messDigest; - - private final MessageEncryptor mcElieceCCA2Cipher; - - private boolean forEncrypting; - - - public McEliecePointchevalDigestCipher(MessageEncryptor mcElieceCCA2Cipher, Digest messDigest) - { - this.mcElieceCCA2Cipher = mcElieceCCA2Cipher; - this.messDigest = messDigest; - } - - - public void init(boolean forEncrypting, - CipherParameters param) - { - - this.forEncrypting = forEncrypting; - AsymmetricKeyParameter k; - - if (param instanceof ParametersWithRandom) - { - k = (AsymmetricKeyParameter)((ParametersWithRandom)param).getParameters(); - } - else - { - k = (AsymmetricKeyParameter)param; - } - - if (forEncrypting && k.isPrivate()) - { - throw new IllegalArgumentException("Encrypting Requires Public Key."); - } - - if (!forEncrypting && !k.isPrivate()) - { - throw new IllegalArgumentException("Decrypting Requires Private Key."); - } - - reset(); - - mcElieceCCA2Cipher.init(forEncrypting, param); - } - - - public byte[] messageEncrypt() - { - if (!forEncrypting) - { - throw new IllegalStateException("McEliecePointchevalDigestCipher not initialised for encrypting."); - } - - byte[] hash = new byte[messDigest.getDigestSize()]; - messDigest.doFinal(hash, 0); - byte[] enc = null; - - try - { - enc = mcElieceCCA2Cipher.messageEncrypt(hash); - } - catch (Exception e) - { - e.printStackTrace(); - } - - - return enc; - } - - - public byte[] messageDecrypt(byte[] ciphertext) - { - byte[] output = null; - if (forEncrypting) - { - throw new IllegalStateException("McEliecePointchevalDigestCipher not initialised for decrypting."); - } - - - try - { - output = mcElieceCCA2Cipher.messageDecrypt(ciphertext); - } - catch (Exception e) - { - e.printStackTrace(); - } - - - return output; - } - - - public void update(byte b) - { - messDigest.update(b); - - } - - public void update(byte[] in, int off, int len) - { - messDigest.update(in, off, len); - - } - - - public void reset() - { - messDigest.reset(); - - } - - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePrivateKeyParameters.java deleted file mode 100644 index 762c2a25..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePrivateKeyParameters.java +++ /dev/null @@ -1,197 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; -import org.bouncycastle.pqc.math.linearalgebra.GF2mField; -import org.bouncycastle.pqc.math.linearalgebra.Permutation; -import org.bouncycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM; - - -public class McEliecePrivateKeyParameters - extends McElieceKeyParameters -{ - - // the OID of the algorithm - private String oid; - - // the length of the code - private int n; - - // the dimension of the code, where <tt>k >= n - mt</tt> - private int k; - - // the underlying finite field - private GF2mField field; - - // the irreducible Goppa polynomial - private PolynomialGF2mSmallM goppaPoly; - - // a k x k random binary non-singular matrix - private GF2Matrix sInv; - - // the permutation used to generate the systematic check matrix - private Permutation p1; - - // the permutation used to compute the public generator matrix - private Permutation p2; - - // the canonical check matrix of the code - private GF2Matrix h; - - // the matrix used to compute square roots in <tt>(GF(2^m))^t</tt> - private PolynomialGF2mSmallM[] qInv; - - /** - * Constructor. - * - * @param oid - * @param n the length of the code - * @param k the dimension of the code - * @param field the field polynomial defining the finite field - * <tt>GF(2<sup>m</sup>)</tt> - * @param goppaPoly the irreducible Goppa polynomial - * @param sInv the matrix <tt>S<sup>-1</sup></tt> - * @param p1 the permutation used to generate the systematic check - * matrix - * @param p2 the permutation used to compute the public generator - * matrix - * @param h the canonical check matrix - * @param qInv the matrix used to compute square roots in - * <tt>(GF(2<sup>m</sup>))<sup>t</sup></tt> - * @param params McElieceParameters - */ - public McEliecePrivateKeyParameters(String oid, int n, int k, GF2mField field, - PolynomialGF2mSmallM goppaPoly, GF2Matrix sInv, Permutation p1, - Permutation p2, GF2Matrix h, PolynomialGF2mSmallM[] qInv, McElieceParameters params) - { - super(true, params); - this.oid = oid; - this.k = k; - this.n = n; - this.field = field; - this.goppaPoly = goppaPoly; - this.sInv = sInv; - this.p1 = p1; - this.p2 = p2; - this.h = h; - this.qInv = qInv; - } - - /** - * Constructor (used by the {@link McElieceKeyFactory}). - * - * @param oid - * @param n the length of the code - * @param k the dimension of the code - * @param encField the encoded field polynomial defining the finite field - * <tt>GF(2<sup>m</sup>)</tt> - * @param encGoppaPoly the encoded irreducible Goppa polynomial - * @param encSInv the encoded matrix <tt>S<sup>-1</sup></tt> - * @param encP1 the encoded permutation used to generate the systematic - * check matrix - * @param encP2 the encoded permutation used to compute the public - * generator matrix - * @param encH the encoded canonical check matrix - * @param encQInv the encoded matrix used to compute square roots in - * <tt>(GF(2<sup>m</sup>))<sup>t</sup></tt> - * @param params McElieceParameters - */ - public McEliecePrivateKeyParameters(String oid, int n, int k, byte[] encField, - byte[] encGoppaPoly, byte[] encSInv, byte[] encP1, byte[] encP2, - byte[] encH, byte[][] encQInv, McElieceParameters params) - { - super(true, params); - this.oid = oid; - this.n = n; - this.k = k; - field = new GF2mField(encField); - goppaPoly = new PolynomialGF2mSmallM(field, encGoppaPoly); - sInv = new GF2Matrix(encSInv); - p1 = new Permutation(encP1); - p2 = new Permutation(encP2); - h = new GF2Matrix(encH); - qInv = new PolynomialGF2mSmallM[encQInv.length]; - for (int i = 0; i < encQInv.length; i++) - { - qInv[i] = new PolynomialGF2mSmallM(field, encQInv[i]); - } - } - - /** - * @return the length of the code - */ - public int getN() - { - return n; - } - - /** - * @return the dimension of the code - */ - public int getK() - { - return k; - } - - /** - * @return the finite field <tt>GF(2<sup>m</sup>)</tt> - */ - public GF2mField getField() - { - return field; - } - - /** - * @return the irreducible Goppa polynomial - */ - public PolynomialGF2mSmallM getGoppaPoly() - { - return goppaPoly; - } - - /** - * @return the k x k random binary non-singular matrix S^-1 - */ - public GF2Matrix getSInv() - { - return sInv; - } - - /** - * @return the permutation used to generate the systematic check matrix - */ - public Permutation getP1() - { - return p1; - } - - /** - * @return the permutation used to compute the public generator matrix - */ - public Permutation getP2() - { - return p2; - } - - /** - * @return the canonical check matrix H - */ - public GF2Matrix getH() - { - return h; - } - - /** - * @return the matrix used to compute square roots in - * <tt>(GF(2<sup>m</sup>))<sup>t</sup></tt> - */ - public PolynomialGF2mSmallM[] getQInv() - { - return qInv; - } - - public String getOIDString() - { - return oid; - } - -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePublicKeyParameters.java deleted file mode 100644 index 6059e2e8..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mceliece/McEliecePublicKeyParameters.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.bouncycastle.pqc.crypto.mceliece; - -import org.bouncycastle.pqc.math.linearalgebra.GF2Matrix; - - -public class McEliecePublicKeyParameters - extends McElieceKeyParameters -{ - - // the OID of the algorithm - private String oid; - - // the length of the code - private int n; - - // the error correction capability of the code - private int t; - - // the generator matrix - private GF2Matrix g; - - /** - * Constructor (used by {@link McElieceKeyFactory}). - * - * @param oid - * @param n the length of the code - * @param t the error correction capability of the code - * @param g the generator matrix - * @param params McElieceParameters - */ - public McEliecePublicKeyParameters(String oid, int n, int t, GF2Matrix g, McElieceParameters params) - { - super(false, params); - this.oid = oid; - this.n = n; - this.t = t; - this.g = new GF2Matrix(g); - } - - /** - * Constructor (used by {@link McElieceKeyFactory}). - * - * @param oid - * @param n the length of the code - * @param t the error correction capability of the code - * @param encG the encoded generator matrix - * @param params McElieceParameters - */ - public McEliecePublicKeyParameters(String oid, int t, int n, byte[] encG, McElieceParameters params) - { - super(false, params); - this.oid = oid; - this.n = n; - this.t = t; - this.g = new GF2Matrix(encG); - } - - /** - * @return the length of the code - */ - public int getN() - { - return n; - } - - /** - * @return the error correction capability of the code - */ - public int getT() - { - return t; - } - - /** - * @return the generator matrix - */ - public GF2Matrix getG() - { - return g; - } - - public String getOIDString() - { - return oid; - - } - - /** - * @return the dimension of the code - */ - public int getK() - { - return g.getNumRows(); - } - -} |