Beispiel #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));
        }
Beispiel #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 });
        }
Beispiel #3
0
 /// <summary>
 /// Initialize this class for CCA2 MPKCS
 /// </summary>
 ///
 /// <param name="N">Length of the code</param>
 /// <param name="K">The dimension of the code</param>
 /// <param name="Gf">The finite field <c>GF(2^m)</c></param>
 /// <param name="Gp">The irreducible Goppa polynomial</param>
 /// <param name="P">The permutation</param>
 /// <param name="H">The canonical check matrix</param>
 /// <param name="QInv">The matrix used to compute square roots in <c>(GF(2^m))^t</c></param>
 internal MPKCPrivateKey(int N, int K, GF2mField Gf, PolynomialGF2mSmallM Gp, Permutation P, GF2Matrix H, PolynomialGF2mSmallM[] QInv)
 {
     m_N         = N;
     m_K         = K;
     m_gField    = Gf;
     m_goppaPoly = Gp;
     m_P1        = P;
     m_H         = H;
     m_qInv      = QInv;
 }
Beispiel #4
0
        /// <summary>
        /// Reads a Private Key from a Stream
        /// </summary>
        ///
        /// <param name="KeyStream">An input stream containing an encoded key</param>
        ///
        /// <exception cref="CryptoAsymmetricException">Thrown if the key could not be loaded</exception>
        public MPKCPrivateKey(Stream KeyStream)
        {
            try
            {
                int          len;
                BinaryReader reader = new BinaryReader(KeyStream);

                // length
                m_N = reader.ReadInt32();
                // dimension
                m_K = reader.ReadInt32();

                // gf
                byte[] gf = reader.ReadBytes(GF_LENGTH);
                m_gField = new GF2mField(gf);

                // gp
                len = reader.ReadInt32();
                byte[] gp = reader.ReadBytes(len);
                m_goppaPoly = new PolynomialGF2mSmallM(m_gField, gp);

                // p1
                len = reader.ReadInt32();
                byte[] p1 = reader.ReadBytes(len);
                m_P1 = new Permutation(p1);

                // check matrix
                len = reader.ReadInt32();
                byte[] h = reader.ReadBytes(len);
                m_H = new GF2Matrix(h);

                // length of first dimension
                len = reader.ReadInt32();
                byte[][] qi = new byte[len][];

                // get the qinv encoded array
                for (int i = 0; i < qi.Length; i++)
                {
                    len   = reader.ReadInt32();
                    qi[i] = reader.ReadBytes(len);
                }

                // assign qinv
                m_qInv = new PolynomialGF2mSmallM[qi.Length];

                for (int i = 0; i < QInv.Length; i++)
                {
                    m_qInv[i] = new PolynomialGF2mSmallM(m_gField, qi[i]);
                }
            }
            catch (Exception ex)
            {
                throw new CryptoAsymmetricException("MPKCPrivateKey:CTor", "The Private key could not be loaded!", ex);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Initialize this class CCA2 MPKCS using encoded byte arrays
        /// </summary>
        ///
        /// <param name="N">Length of the code</param>
        /// <param name="K">The dimension of the code</param>
        /// <param name="Gf">Encoded field polynomial defining the finite field <c>GF(2^m)</c></param>
        /// <param name="Gp">Encoded irreducible Goppa polynomial</param>
        /// <param name="P">The encoded permutation</param>
        /// <param name="H">Encoded canonical check matrix</param>
        /// <param name="QInv">The encoded matrix used to compute square roots in <c>(GF(2^m))^t</c></param>
        public MPKCPrivateKey(int N, int K, byte[] Gf, byte[] Gp, byte[] P, byte[] H, byte[][] QInv)
        {
            m_N         = N;
            m_K         = K;
            m_gField    = new GF2mField(Gf);
            m_goppaPoly = new PolynomialGF2mSmallM(m_gField, Gp);
            m_P1        = new Permutation(P);
            m_H         = new GF2Matrix(H);
            m_qInv      = new PolynomialGF2mSmallM[QInv.Length];

            for (int i = 0; i < QInv.Length; i++)
            {
                m_qInv[i] = new PolynomialGF2mSmallM(m_gField, QInv[i]);
            }
        }
Beispiel #6
0
        private void Dispose(bool Disposing)
        {
            if (!m_isDisposed && Disposing)
            {
                try
                {
                    if (m_gField != null)
                    {
                        m_gField.Clear();
                        m_gField = null;
                    }
                    if (m_goppaPoly != null)
                    {
                        m_goppaPoly.Clear();
                        m_goppaPoly = null;
                    }
                    if (m_H != null)
                    {
                        m_H.Clear();
                        m_H = null;
                    }
                    if (m_P1 != null)
                    {
                        m_P1.Clear();
                        m_P1 = null;
                    }
                    if (m_qInv != null)
                    {
                        for (int i = 0; i < m_qInv.Length; i++)
                        {
                            m_qInv[i].Clear();
                            m_qInv[i] = null;
                        }
                        m_qInv = null;
                    }
                    m_K = 0;
                    m_N = 0;
                }
                catch { }

                m_isDisposed = true;
            }
        }
Beispiel #7
0
        private void Dispose(bool Disposing)
        {
            if (!_isDisposed && Disposing)
            {
                try
                {
                    if (_gField != null)
                    {
                        _gField.Clear();
                        _gField = null;
                    }
                    if (_goppaPoly != null)
                    {
                        _goppaPoly.Clear();
                        _goppaPoly = null;
                    }
                    if (_H != null)
                    {
                        _H.Clear();
                        _H = null;
                    }
                    if (_P1 != null)
                    {
                        _P1.Clear();
                        _P1 = null;
                    }
                    if (_qInv != null)
                    {
                        for (int i = 0; i < _qInv.Length; i++)
                        {
                            _qInv[i].Clear();
                            _qInv[i] = null;
                        }
                        _qInv = null;
                    }
                    _K = 0;
                    _N = 0;
                }
                catch { }

                _isDisposed = true;
            }
        }