Example #1
0
        /// <summary>
        /// Generate an encryption Key pair
        /// </summary>
        ///
        /// <returns>A McElieceKeyPair containing public and private keys</returns>
        public IAsymmetricKeyPair GenerateKeyPair()
        {
            // finite field GF(2^m)
            GF2mField field = new GF2mField(_M, _fieldPoly);
            // irreducible Goppa polynomial
            PolynomialGF2mSmallM gp   = new PolynomialGF2mSmallM(field, _T, PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, _rndEngine);
            PolynomialRingGF2m   ring = new PolynomialRingGF2m(field, gp);

            // matrix for computing square roots in (GF(2^m))^t
            PolynomialGF2mSmallM[] qInv = ring.SquareRootMatrix;
            // generate canonical check matrix
            GF2Matrix h = GoppaCode.CreateCanonicalCheckMatrix(field, gp);

            // compute short systematic form of check matrix
            GoppaCode.MaMaPe mmp    = GoppaCode.ComputeSystematicForm(h, _rndEngine);
            GF2Matrix        shortH = mmp.SecondMatrix;
            Permutation      p      = mmp.Permutation;
            // 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.RowCount;
            // generate keys
            IAsymmetricKey pubKey  = new MPKCPublicKey(_N, _T, shortG);
            IAsymmetricKey privKey = new MPKCPrivateKey(_N, k, field, gp, p, h, qInv);

            // return key pair
            return(new MPKCKeyPair(pubKey, privKey));
        }
Example #2
0
        /// <summary>
        /// The McEliece decryption primitive
        /// </summary>
        ///
        /// <param name="PrivateKey">The private key</param>
        /// <param name="C">The ciphertext vector <c>c = m*G + z</c></param>
        ///
        /// <returns>The message vector <c>m</c> and the error vector <c>z</c></returns>
        public static GF2Vector[] Decrypt(MPKCPrivateKey PrivateKey, GF2Vector C)
        {
            // obtain values from private key
            int                  k     = PrivateKey.K;
            Permutation          p     = PrivateKey.P1;
            GF2mField            field = PrivateKey.GF;
            PolynomialGF2mSmallM gp    = PrivateKey.GP;
            GF2Matrix            h     = PrivateKey.H;

            PolynomialGF2mSmallM[] q = PrivateKey.QInv;

            // 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 });
        }