org.spongycastle.pqc.jcajce.provider.mceliece.McElieceCCA2Primitives Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of prov Show documentation
Show all versions of prov Show documentation
Spongy Castle is a package-rename (org.bouncycastle.* to org.spongycastle.*) of Bouncy Castle
intended for the Android platform. Android unfortunately ships with a stripped-down version of
Bouncy Castle, which prevents easy upgrades - Spongy Castle overcomes this and provides a full,
up-to-date version of the Bouncy Castle cryptographic libs.
The newest version!
package org.spongycastle.pqc.jcajce.provider.mceliece;
import org.spongycastle.pqc.crypto.mceliece.McElieceCCA2PrivateKeyParameters;
import org.spongycastle.pqc.crypto.mceliece.McElieceCCA2PublicKeyParameters;
import org.spongycastle.pqc.math.linearalgebra.GF2Matrix;
import org.spongycastle.pqc.math.linearalgebra.GF2Vector;
import org.spongycastle.pqc.math.linearalgebra.GF2mField;
import org.spongycastle.pqc.math.linearalgebra.GoppaCode;
import org.spongycastle.pqc.math.linearalgebra.Permutation;
import org.spongycastle.pqc.math.linearalgebra.PolynomialGF2mSmallM;
import org.spongycastle.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 m*G + z
*/
public static GF2Vector encryptionPrimitive(BCMcElieceCCA2PublicKey pubKey,
GF2Vector m, GF2Vector z)
{
GF2Matrix matrixG = pubKey.getG();
Vector mG = matrixG.leftMultiplyLeftCompactForm(m);
return (GF2Vector)mG.add(z);
}
public static GF2Vector encryptionPrimitive(McElieceCCA2PublicKeyParameters pubKey,
GF2Vector m, GF2Vector z)
{
GF2Matrix matrixG = pubKey.getG();
Vector mG = matrixG.leftMultiplyLeftCompactForm(m);
return (GF2Vector)mG.add(z);
}
/**
* The McEliece decryption primitive.
*
* @param privKey the private key
* @param c the ciphertext vector c = m*G + z
* @return the message vector m and the error vector z
*/
public static GF2Vector[] decryptionPrimitive(
BCMcElieceCCA2PrivateKey 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};
}
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};
}
}