Beispiel #1
0
        public string Decrypt(VectorND cipher)
        {
            List <char> result     = new List <char>();
            int         blockCount = cipher.dim / dim;

            for (int i = 0; i < blockCount; i++)
            {
                MatrixND cipherVector = new MatrixND(dim, 1);
                for (int j = 0; j < dim; j++)
                {
                    cipherVector[j, 0] = (double)cipher.values[i * dim + j];
                }

                MatrixND babai = privateKeyR1 * cipherVector;
                for (int j = 0; j < dim; j++)
                {
                    babai[j, 0] = Math.Round(babai[j, 0]);
                }

                MatrixND messageVector = publicKeyB1 * privateKeyR * babai;

                for (int j = 0; j < dim; j++)
                {
                    int messageInt = (int)Math.Round(messageVector[j, 0]);
                    if (messageInt == 0)
                    {
                        break;
                    }
                    result.Add(Convert.ToChar(messageInt));
                }
            }

            return(new string(result.ToArray()));
        }
Beispiel #2
0
        public VectorND Encrypt(string message)
        {
            char[] chars = message.ToCharArray();
            int    rem;
            int    blockCount = Math.DivRem(chars.Length, dim, out rem);

            if (rem > 0)
            {
                blockCount++;
            }

            VectorND cipher = new VectorND(dim * blockCount);

            for (int i = 0; i < blockCount; i++)
            {
                MatrixND messagePart = new MatrixND(dim, 1);
                for (int j = 0; j < dim && chars.Length > i * dim + j; j++)
                {
                    messagePart[j, 0] = chars[i * dim + j];
                }

                MatrixND cipherPart = publicKeyB * messagePart + errorVectorIntern;
                for (int j = 0; j < dim; j++)
                {
                    cipher.values[i * dim + j] = (int)cipherPart[j, 0];
                }
            }

            return(cipher);
        }
Beispiel #3
0
        public GGHModel(int dim, int l, VectorND errorVector)
        {
            this.dim = dim;
            this.l   = l;
            k        = (int)Math.Round(l * Math.Sqrt(dim));

            do
            {
                GeneratePrivateKey();
                GeneratePublicKey();
            } while (privateKeyR.Det() == 0 || publicKeyB.Det() == 0);

            privateKeyR1 = privateKeyR.Invert();
            publicKeyB1  = publicKeyB.Invert();

            GenerateLattice();

            if (errorVector == null || errorVector.dim != dim)
            {
                GenerateErrorVector();
            }
            else
            {
                this.errorVector  = errorVector;
                errorVectorIntern = new MatrixND(dim, 1);
                for (int i = 0; i < dim; i++)
                {
                    errorVectorIntern[i, 0] = (double)errorVector.values[i];
                }
            }
        }
Beispiel #4
0
 public MerkleHellmanModel(VectorND privateKey, BigInteger r, BigInteger mod)
 {
     dim             = privateKey.dim;
     this.privateKey = privateKey;
     this.r          = r;
     this.mod        = mod;
     rI = ModInverse(r, mod);
     ComputePublicKey();
 }
Beispiel #5
0
        public VectorND Add(VectorND v2)
        {
            VectorND result = new VectorND(values.Length);

            for (int i = 0; i < dim; i++)
            {
                result.values[i] = values[i] + v2.values[i];
            }
            return(result);
        }
Beispiel #6
0
 public void SetErrorVectorManually(VectorND newErrorVector)
 {
     errorVector       = newErrorVector;
     dim               = newErrorVector.dim;
     errorVectorIntern = new MatrixND(dim, 1);
     for (int i = 0; i < dim; i++)
     {
         errorVectorIntern[i, 0] = (int)errorVector.values[i];
     }
 }
Beispiel #7
0
        public VectorND Multiply(BigInteger scalar)
        {
            VectorND result = new VectorND(values.Length);

            for (int i = 0; i < dim; i++)
            {
                result.values[i] = values[i] * scalar;
            }
            return(result);
        }
Beispiel #8
0
        public BigInteger Multiply(VectorND v2)
        {
            BigInteger result = 0;

            for (int i = 0; i < dim; i++)
            {
                result += values[i] * v2.values[i];
            }
            return(result);
        }
Beispiel #9
0
        public VectorND GetMinimalReducedVector()
        {
            VectorND minimalVector = ReducedVectors[0];

            foreach (VectorND reducedVector in ReducedVectors.Where(reducedVector => reducedVector.Length < minimalVector.Length))
            {
                minimalVector = reducedVector;
            }
            return(minimalVector);
        }
Beispiel #10
0
        public string Decrypt(VectorND vector)
        {
            BigInteger[] decryptVector = new BigInteger[vector.dim];
            for (int i = 0; i < vector.dim; i++)
            {
                BigInteger bigInt = (vector.values[i] * rI) % mod;
                decryptVector[i] = bigInt;
            }

            string messageBinary = "";

            for (int i = 0; i < decryptVector.Length; i++)
            {
                string blockPart = "";
                for (int j = privateKey.dim - 1; j >= 0; j--)
                {
                    if (decryptVector[i] >= privateKey.values[j])
                    {
                        decryptVector[i] -= privateKey.values[j];
                        blockPart        += "1";
                    }
                    else
                    {
                        blockPart += "0";
                    }
                }

                //Beim letzten Block kürzen
                if (i == decryptVector.Length - 1)
                {
                    int redudandBits = (messageBinary.Length + blockPart.Length) % maxBitLength;
                    if (redudandBits > 0)
                    {
                        blockPart = blockPart.Remove(0, redudandBits);
                    }
                    if (blockPart.Length >= maxBitLength && blockPart.Substring(0, maxBitLength).IndexOf('1') == -1)
                    {
                        blockPart = blockPart.Remove(0, maxBitLength);
                    }
                }

                blockPart      = new string(blockPart.Reverse().ToArray());
                messageBinary += blockPart;
            }

            List <byte> bytes = new List <byte>();

            for (int i = 0; i < messageBinary.Length; i += maxBitLength)
            {
                bytes.Add(Convert.ToByte(messageBinary.Substring(i, maxBitLength), 2));
            }

            return(Encoding.UTF8.GetString(bytes.ToArray()));
        }
Beispiel #11
0
        private void ComputePublicKey()
        {
            publicKey = new VectorND(dim);

            for (int i = 0; i < dim; i++)
            {
                BigInteger bigInt = (privateKey.values[i] * r) % mod;
                publicKey.values[i] = bigInt;
            }

            Debug.WriteLine(publicKey);
        }
Beispiel #12
0
 public LatticeND(int n, int m, bool transpose)
 {
     Vectors        = new VectorND[n];
     ReducedVectors = new VectorND[n];
     N = n;
     M = m;
     for (int i = 0; i < N; i++)
     {
         Vectors[i] = new VectorND(M);
     }
     UseRowVectors = transpose;
 }
Beispiel #13
0
        public void GaussianReduce()
        {
            ReductionMethod = ReductionMethods.reduceGauss;
            VectorND v1 = Vectors[0];
            VectorND v2 = Vectors[1];

            ReductionSteps     = new List <VectorND[]>();
            UnimodTransVectors = new VectorND[2];
            VectorND u1 = new VectorND(new BigInteger[] { 1, 0 });
            VectorND u2 = new VectorND(new BigInteger[] { 0, 1 });

            BigInteger rem;

            do
            {
                if (v1.Length > v2.Length)
                {
                    Util.Swap(ref v1, ref v2);
                    Util.Swap(ref u1, ref u2);
                    ReductionSteps.Add(new[] { v1, v2 });
                }
                BigInteger t = BigInteger.DivRem(v1 * v2, v1.LengthSquared, out rem);
                //Bei der Division von BigIntegers muss noch auf korrektes Runden geprüft werden
                if (BigInteger.Abs(rem) > v1.LengthSquared / 2)
                {
                    t += rem.Sign;
                }
                v2 = v2 - v1 * t;
                u2 = u2 - u1 * t;
                ReductionSteps.Add(new[] { v1, v2 });
            } while (v1.Length > v2.Length);

            //Damit ein spitzer Winkel entsteht
            if (Settings.Default.forceAcuteAngle)
            {
                BigInteger.DivRem(v1 * v2, v1.LengthSquared, out rem);
                if (rem.Sign == -1)
                {
                    v2 = v2 * -1;
                    u2 = u2 * -1;
                    ReductionSteps.Add(new[] { v1, v2 });
                }
            }

            ReducedVectors[0]   = v1;
            ReducedVectors[1]   = v2;
            UnimodTransVectors  = new[] { u1, u2 };
            AngleReducedVectors = ReducedVectors[0].AngleBetween(ReducedVectors[1]);
            CalculateDensity();
        }
Beispiel #14
0
        public void GenerateErrorVector()
        {
            Random random = new Random();

            errorVector       = new VectorND(dim);
            errorVectorIntern = new MatrixND(dim, 1);

            for (int i = 0; i < dim; i++)
            {
                int randomSigma = random.NextDouble() < 0.5 ? sigma : -sigma;
                errorVector.values[i]   = randomSigma;
                errorVectorIntern[i, 0] = randomSigma;
            }
        }
Beispiel #15
0
 public LatticeND(VectorND[] vectors, bool useRowVectors)
 {
     Vectors        = vectors;
     UseRowVectors  = useRowVectors;
     N              = vectors.Length;
     M              = vectors[0].dim;
     ReducedVectors = new VectorND[N];
     if (N == M)
     {
         Determinant = CalculateDeterminant(Vectors);
     }
     if (Vectors.Length == 2)
     {
         AngleBasisVectors = Vectors[0].AngleBetween(Vectors[1]);
     }
 }
Beispiel #16
0
        public void GenerateLattice()
        {
            lattice = new LatticeND(dim, dim, false);

            //Umwandlung der Matrizeneinträge von double zu BigInt und damit Umwandlung der Matrizen zu einem Gitter

            VectorND[] privateVectors = new VectorND[dim];
            for (int i = 0; i < dim; i++)
            {
                BigInteger[] privateBigInts = new BigInteger[dim];
                for (int j = 0; j < dim; j++)
                {
                    privateBigInts[j] = new BigInteger(privateKeyR[j, i]);
                }
                privateVectors[i] = new VectorND(privateBigInts);
            }
            lattice.ReducedVectors = privateVectors;

            VectorND[] publicVectors = new VectorND[dim];
            for (int i = 0; i < dim; i++)
            {
                BigInteger[] publicBigInts = new BigInteger[dim];
                for (int j = 0; j < dim; j++)
                {
                    publicBigInts[j] = new BigInteger(publicKeyB[j, i]);
                }
                publicVectors[i] = new VectorND(publicBigInts);
            }
            lattice.Vectors = publicVectors;

            if (transU == null)
            {
                return;
            }

            VectorND[] transVectors = new VectorND[dim];
            for (int i = 0; i < dim; i++)
            {
                BigInteger[] transBigInts = new BigInteger[dim];
                for (int j = 0; j < dim; j++)
                {
                    transBigInts[j] = new BigInteger(transU[j, i]);
                }
                transVectors[i] = new VectorND(transBigInts);
            }
            lattice.UnimodTransVectors = transVectors;
        }
Beispiel #17
0
        public GGHModel(int dim, MatrixND privateKeyR, MatrixND publicKeyB, VectorND errorVector)
        {
            this.dim         = dim;
            this.privateKeyR = privateKeyR;
            this.publicKeyB  = publicKeyB;
            privateKeyR1     = privateKeyR.Invert();
            publicKeyB1      = publicKeyB.Invert();

            GenerateLattice();

            this.errorVector  = errorVector;
            errorVectorIntern = new MatrixND(dim, 1);
            for (int i = 0; i < dim; i++)
            {
                errorVectorIntern[i, 0] = (double)errorVector.values[i];
            }
        }
Beispiel #18
0
        public void GenerateRandomVectors(bool checkForGoodBasis, BigInteger codomainStart, BigInteger codomainEnd)
        {
            VectorND[] newVectorNds = new VectorND[N];
            BigInteger det          = 0;
            int        counter      = 0;

            while (true)
            {
                for (int i = 0; i < N; i++)
                {
                    BigInteger[] vector = new BigInteger[M];
                    newVectorNds[i] = new VectorND(M);

                    for (int j = 0; j < M; j++)
                    {
                        vector[j] = Util.ComputeRandomBigInt(codomainStart, codomainEnd);
                    }

                    for (int k = 0; k < vector.Length; k++)
                    {
                        newVectorNds[i].values[k] = vector[k];
                    }
                }

                if (N == M)
                {
                    det = CalculateDeterminant(newVectorNds);
                }
                if ((N != M || det != 0) && (!checkForGoodBasis || IsGoodBasis(newVectorNds)))
                {
                    break;
                }
                counter++;
                if (counter > 1024)
                {
                    throw new Exception(Languages.errorFailedToGenerateLattice);
                }
            }

            Vectors     = (VectorND[])newVectorNds.Clone();
            Determinant = det;
            if (Vectors.Length == 2)
            {
                AngleBasisVectors = Vectors[0].AngleBetween(Vectors[1]);
            }
        }
Beispiel #19
0
        public void Transpose()
        {
            VectorND[] tempVectors = (VectorND[])Vectors.Clone();

            int tempN = N;

            N = M;
            M = tempN;

            Vectors = new VectorND[N];
            for (int i = 0; i < N; i++)
            {
                Vectors[i] = new VectorND(M);
                for (int j = 0; j < M; j++)
                {
                    Vectors[i].values[j] = tempVectors[j].values[i];
                }
            }
        }
Beispiel #20
0
        private void GenerateSuperincreasingSequence()
        {
            List <BigInteger> values = new List <BigInteger>(dim);

            BigInteger tempGenMult   = generatingMultiplicator;
            bool       sequenceFound = false;

            while (!sequenceFound)
            {
                for (int i = 0; i < dim; i++)
                {
                    BigInteger sum = Util.Sum(values);
                    if (sum == 0)
                    {
                        sum = 1;
                    }
                    values.Add(Util.ComputeRandomBigInt(sum + 1, sum * tempGenMult));
                }
                double density = dim / BigInteger.Log(values[dim - 1], 2);

                if (density > 0.646 || !IsSuperincreasingSequence(values))
                {
                    tempGenMult *= 2;
                    values       = new List <BigInteger>(dim);
                }
                else
                {
                    sequenceFound = true;
                }
            }

            //Könnte hier weg und stattdessen in der dazugehörigen Test-Methode verwendet werden
            //if (!IsSuperincreasingSequence(values))
            //    throw new Exception(Languages.errorGeneratingSuperincSequence);

            privateKey = new VectorND(values.ToArray());
            Debug.WriteLine(privateKey);
        }
Beispiel #21
0
        public string Cryptanalysis(VectorND cipher, Paragraph paragraph)
        {
            string messageBinary = "";

            foreach (BigInteger value in cipher.values)
            {
                //BigInteger tempValue = value;

                LatticeND lattice = TransformToLattice(value);

                //Anmerkung: Der zweite Versuch nach LAGARIAS/ODLYZKO, S.232 funktioniert leider nicht,
                //daher wurde dieser Teil auskommentiert

                //for (int j = 0; j <= 1; j++)
                //{
                lattice.LLLReduce();

                BigInteger[] vector = FindBinaryVector(lattice.ReducedVectors, value);

                //    if (vector != null)
                //        break;

                //    //Zweiter Versuch
                //    tempValue = Util.Sum(publicKey.ToList()) - tempValue;
                //    lattice = TransformToLattice(tempValue);
                //}

                if (vector == null)
                {
                    throw new Exception();
                }

                if (paragraph != null)
                {
                    paragraph.Inlines.Add("--------------------\r\n");
                    paragraph.Inlines.Add(new Bold(new Run(Languages.labelCurrentBlock)));
                    paragraph.Inlines.Add(" " + value + "\r\n");
                    paragraph.Inlines.Add(new Bold(new Run(Languages.labelLatticeBasis)));
                    paragraph.Inlines.Add(" " + lattice.LatticeToString() + "\r\n");
                    paragraph.Inlines.Add(new Bold(new Run(Languages.labelReducedLatticeBasis)));
                    paragraph.Inlines.Add(" " + lattice.LatticeReducedToString() + "\r\n");
                    paragraph.Inlines.Add(new Bold(new Run(Languages.labelFoundVector)));
                    paragraph.Inlines.Add(" " + new VectorND(vector) + "\r\n");
                }

                for (int k = 0; k < dim; k++)
                {
                    messageBinary += vector[k];
                }
            }

            int redudandBits = (messageBinary.Length) % maxBitLength;

            if (redudandBits > 0)
            {
                messageBinary = messageBinary.Remove(messageBinary.Length - redudandBits);
            }
            if (messageBinary.Length >= maxBitLength && messageBinary.Substring(messageBinary.Length - maxBitLength).IndexOf('1') == -1)
            {
                messageBinary = messageBinary.Remove(messageBinary.Length - maxBitLength);
            }

            if (paragraph != null)
            {
                paragraph.Inlines.Add("--------------------\r\n");
                paragraph.Inlines.Add(new Bold(new Run(Languages.labelPlainTextBinary)));
                paragraph.Inlines.Add(" " + messageBinary + "\r\n");
            }

            List <byte> bytes = new List <byte>();

            for (int i = 0; i < messageBinary.Length; i += maxBitLength)
            {
                bytes.Add(Convert.ToByte(messageBinary.Substring(i, maxBitLength), 2));
            }

            string messageUTF8 = Encoding.UTF8.GetString(bytes.ToArray());

            if (paragraph != null)
            {
                paragraph.Inlines.Add(new Bold(new Run(Languages.labelPlainTextUTF8)));
                paragraph.Inlines.Add(" " + messageUTF8 + "\r\n");
            }

            return(messageUTF8);
        }
Beispiel #22
0
 public double AngleBetween(VectorND v2)
 {
     return(Math.Acos(((double)Multiply(v2) / (Length * v2.Length))) * (180 / Math.PI));
 }
Beispiel #23
0
        public void LLLReduce()
        {
            ReductionMethod          = ReductionMethods.reduceLLL;
            BigInteger[,] basisArray = new BigInteger[N, M];
            BigInteger[,] transArray = new BigInteger[N, N];
            List <BigInteger[, ]> stepList = new List <BigInteger[, ]>();

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < M; j++)
                {
                    basisArray[i, j] = Vectors[i].values[j];
                }
            }

            using (var nativeObject = new NTL_Wrapper())
            {
                nativeObject.LLLReduce(basisArray, transArray, stepList, N, M, 0.99);
            }

            ReducedVectors = new VectorND[N];
            for (int i = 0; i < N; i++)
            {
                ReducedVectors[i] = new VectorND(M);
                for (int j = 0; j < M; j++)
                {
                    ReducedVectors[i].values[j] = basisArray[i, j];
                }
            }

            if (M == 2 && N == 2)
            {
                AngleReducedVectors = ReducedVectors[0].AngleBetween(ReducedVectors[1]);
                CalculateDensity();
            }

            UnimodTransVectors = new VectorND[N];
            for (int i = 0; i < N; i++)
            {
                UnimodTransVectors[i] = new VectorND(N);
                for (int j = 0; j < N; j++)
                {
                    UnimodTransVectors[i].values[j] = transArray[i, j];
                }
            }

            ReductionSteps = new List <VectorND[]>();
            foreach (var step in stepList)
            {
                VectorND[] stepVectors = new VectorND[N];
                for (int i = 0; i < N; i++)
                {
                    stepVectors[i] = new VectorND(M);
                    for (int j = 0; j < M; j++)
                    {
                        stepVectors[i].values[j] = step[i, j];
                    }
                }
                ReductionSteps.Add(stepVectors);
            }
        }