* @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);
}