예제 #1
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 });
        }
예제 #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 };
        }
예제 #3
0
        private void TestEncode()
        {
            MPKCParameters     mpar  = (MPKCParameters)MPKCParamSets.MPKCFM11T40S256.DeepCopy();
            MPKCKeyGenerator   mkgen = new MPKCKeyGenerator(mpar);
            IAsymmetricKeyPair akp   = mkgen.GenerateKeyPair();

            MPKCPublicKey pub = (MPKCPublicKey)akp.PublicKey;

            byte[] enc = pub.ToBytes();
            using (MPKCPublicKey pub2 = MPKCPublicKey.From(enc))
            {
                if (!pub.Equals(pub2))
                {
                    throw new Exception("EncryptionKey: public key comparison test failed!");
                }
                if (pub.GetHashCode() != pub2.GetHashCode())
                {
                    throw new Exception("EncryptionKey: public key hash test failed!");
                }
            }
            OnProgress(new TestEventArgs("Passed public key serialization"));

            MemoryStream pubstr = pub.ToStream();

            using (MPKCPublicKey pub2 = MPKCPublicKey.From(pubstr))
            {
                if (!pub.Equals(pub2))
                {
                    throw new Exception("EncryptionKey: public key comparison test failed!");
                }
                if (pub.GetHashCode() != pub2.GetHashCode())
                {
                    throw new Exception("EncryptionKey: public key hash test failed!");
                }
            }
            pubstr.Dispose();
            OnProgress(new TestEventArgs("Passed public key stream test"));

            MPKCPrivateKey pri = (MPKCPrivateKey)akp.PrivateKey;

            enc = pri.ToBytes();
            using (MPKCPrivateKey pri2 = new MPKCPrivateKey(enc))
            {
                if (!pri.Equals(pri2))
                {
                    throw new Exception("EncryptionKey: private key comparison test failed!");
                }
                if (pri.GetHashCode() != pri2.GetHashCode())
                {
                    throw new Exception("EncryptionKey: private key hash test failed!");
                }
            }
            OnProgress(new TestEventArgs("Passed private key serialization"));

            MemoryStream pristr = pri.ToStream();

            using (MPKCPrivateKey pri2 = MPKCPrivateKey.From(pristr))
            {
                if (!pri.Equals(pri2))
                {
                    throw new Exception("EncryptionKey: private key comparison test failed!");
                }
                if (pri.GetHashCode() != pri2.GetHashCode())
                {
                    throw new Exception("EncryptionKey: private key hash test failed!");
                }
            }
            pristr.Dispose();
            OnProgress(new TestEventArgs("Passed private key stream test"));

            using (MPKCEncrypt mpe = new MPKCEncrypt(mpar))
            {
                mpe.Initialize(akp.PublicKey);

                int    sz   = mpe.MaxPlainText - 1;
                byte[] data = new byte[sz];
                new VTDev.Libraries.CEXEngine.Crypto.Prng.CSPPrng().GetBytes(data);

                enc = mpe.Encrypt(data);

                mpe.Initialize(akp.PrivateKey);
                byte[] dec = mpe.Decrypt(enc);

                if (!Evaluate.AreEqual(dec, data))
                {
                    throw new Exception("EncryptionKey: decryption failure!");
                }
                OnProgress(new TestEventArgs("Passed encryption test"));
            }

            pri.Dispose();
            pub.Dispose();
        }