Exemple #1
0
        // maps single character of plain text to eliptic curve point is not optimal
        // - its slow and ciphertext is large :( needs remake
        // - Koblitz’s Method for Encoding Plaintext
        // - http://informatika.stei.itb.ac.id/~rinaldi.munir/Kriptografi/2014-2015/IJCSE10-02-05-08.pdf
        #region ENCRYPTION - char mapping

        ///// <summary>
        ///// Encrypts chars of plain text to cipher text.
        ///// one char message is represented by 2 eliptic curve points
        ///// in comprimed form after encryption.
        ///// </summary>
        ///// <param name="plainText">the plain text</param>
        ///// <param name="publicKey">the public key</param>
        ///// <returns>cipherText</returns>
        //public string Encrypt(string plainText, string publicKey)
        //{
        //    string cipher = "";
        //    ElipticCurvePoint Q = serialiser.FromHex(publicKey);
        //    foreach (char c in plainText)
        //    {
        //        BigInteger k = rnd.Next(1, curve.N - 1);
        //        ElipticCurvePoint C1 = calculator.Multiply(k, curve.G);
        //        ElipticCurvePoint C2 = calculator.Add(CharToPoint(c), calculator.Multiply(k, Q));
        //        cipher += serialiser.ToHex(C1) + serialiser.ToHex(C2);
        //    }
        //    return cipher;
        //}

        ///// <summary>
        ///// Decrypts cipherText in plainText
        ///// </summary>
        ///// <param name="cipher">cipher text</param>
        ///// <param name="privateKey">private key</param>
        ///// <returns>original plain text</returns>
        //public string Decrypt(string cipher, string privateKey)
        //{
        //    BigInteger pk = BigInteger.Parse(privateKey, NumberStyles.HexNumber);
        //    string message = "";
        //    foreach (string c in Split(cipher, curve.BitSize / 2 + 4))
        //    {
        //        string c1 = c.Substring(0, c.Length / 2);
        //        string c2 = c.Substring(c.Length / 2);
        //        ElipticCurvePoint C1 = serialiser.FromHex(c1);
        //        ElipticCurvePoint C2 = serialiser.FromHex(c2);
        //        message += PointTochar(calculator.Add(C2, calculator.Inverse(calculator.Multiply(pk, C1))));
        //    }
        //    return message;
        //}

        ///// <summary>
        ///// maps single utf-16 code unit to eliptic curve point.
        ///// see - standard probabilistic encoding
        ///// </summary>
        ///// <param name="m">the character to be mapped</param>
        ///// <returns>eliptic curve point</returns>
        //private ElipticCurvePoint CharToPoint(char m)
        //{
        //    BigInteger k = curve.P / int.MaxValue;
        //    BigInteger mkplus = k.ModMul(m, curve.P);
        //    while (true)
        //    {
        //        mkplus = mkplus.ModAdd(1, curve.P);
        //        ElipticCurvePoint mappedPoint = calculator.FindPointByX(mkplus);
        //        if (mappedPoint != null)
        //            return mappedPoint;
        //    }
        //}

        ///// <summary>
        ///// Gets char from eliptic curve point
        ///// see - standard probabilistic encoding
        /////     - Koblitz’s Method for Encoding Plaintext
        /////     - http://informatika.stei.itb.ac.id/~rinaldi.munir/Kriptografi/2014-2015/IJCSE10-02-05-08.pdf
        ///// </summary>
        ///// <param name="point">eliptic curve point</param>
        ///// <returns>character</returns>
        //private char PointTochar(ElipticCurvePoint point)
        //{
        //    BigInteger k = curve.P / int.MaxValue;
        //    return (char)((point.X - 1) / k);
        //}

        #endregion

        // maps block of text into eliptic curve point
        // faster safier and more optimal for cipher text size and speed
        // - Proposed Message Mapping Scheme
        // - http://onlinelibrary.wiley.com/doi/10.1002/sec.1702/full
        #region ENCRYPTION - textblocks mappig

        /// <summary>
        /// Encrypts chars of plain text to cipher text.
        /// one block of message text is represented by 2 eliptic curve points
        /// in comprimed form after encryption.
        /// </summary>
        /// <param name="plainText">the plain text</param>
        /// <param name="publicKey">the public key</param>
        /// <returns>cipherText</returns>
        public byte[] Encrypt(string plainText, byte[] publicKey, Encoding enc, bool comprimed = false)
        {
            List <ElipticCurvePoint> result = new List <ElipticCurvePoint>();
            int encByteSize = enc.GetBytes("a").Length;
            int M           = ((curve.BitSize / 8) - 1) / encByteSize * encByteSize;
            int N           = curve.BitSize / 8 - M;

            byte[]            plainTextBytes = enc.GetBytes(plainText);
            ElipticCurvePoint Q = serialiser.DeserialisePoint(publicKey);

            for (int i = 0; i *M <= plainTextBytes.Length; i++)
            {
                byte[] buffer = new byte[M + N];
                Buffer.BlockCopy(plainTextBytes, i * M, buffer, N, Math.Min(M, plainTextBytes.Length - i * M));
                BigInteger        x     = new BigInteger(buffer);
                ElipticCurvePoint point = calculator.FindPointByX(x);
                while (point == null)
                {
                    point = calculator.FindPointByX(x++);
                }

                BigInteger        k  = rnd.Next(1, curve.N - 1);
                ElipticCurvePoint C1 = calculator.Multiply(k, curve.G);
                ElipticCurvePoint C2 = calculator.Add(point, calculator.Multiply(k, Q));
                result.Add(C1);
                result.Add(C2);
            }
            return(serialiser.SerialisePoints(result, comprimed));
        }
Exemple #2
0
 /// <summary>
 /// gets inverse point to specific point.
 /// </summary>
 /// <param name="point">eliptic curve point</param>
 /// <returns>inverse point</returns>
 public ElipticCurvePoint Inverse(ElipticCurvePoint point)
 {
     if (point == null)
     {
         throw new ArgumentException("cannot find an inverse of zero point.. ");
     }
     return(new ElipticCurvePoint(point.X, point.Y.ModNeg(curve.P)));
 }
Exemple #3
0
 /// <summary>
 /// checks if eliptic curve point lies on curve
 /// </summary>
 /// <param name="p"></param>
 /// <returns>
 /// true - point lies on curve
 /// false - point doesnt lie on curve
 /// </returns>
 internal bool IsCurvePoint(ElipticCurvePoint p)
 {
     if (p == null)
     {
         return(true);
     }
     //return p.Y.ModPow(2, curve.P).ModEquals(p.X.ModPow(3, curve.P).ModAdd(p.X.ModMul(curve.A, curve.P), curve.P).ModAdd(curve.B, curve.P), curve.P);
     return(BigInteger.ModPow(p.Y, 2, curve.P) == (BigInteger.ModPow(p.X, 3, curve.P) + p.X * curve.A + curve.B).Mod(curve.P));
 }
Exemple #4
0
 /// <summary>
 /// set parameters of eliptic curve
 /// </summary>
 /// <param name="p"></param>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <param name="g"></param>
 /// <param name="n"></param>
 /// <param name="h"></param>
 /// <param name="bitSize"></param>
 private ElipticCurve(BigInteger p, BigInteger a, BigInteger b, ElipticCurvePoint g, BigInteger n, BigInteger h, int bitSize, string name)
 {
     P       = p;
     A       = a;
     B       = b;
     G       = g;
     N       = n; //skontroluj bod 3 v diplomovke aj s G
     H       = h;
     BitSize = bitSize;
     Name    = name;
 }
Exemple #5
0
        public byte[] SharedSecret(byte[] privateKey, byte[] publicKey)
        {
            BigInteger        privateK = new BigInteger(privateKey);
            ElipticCurvePoint publicK  = serialiser.DeserialisePoint(publicKey);
            ElipticCurvePoint P        = calculator.Multiply(privateK, publicK);

            if (P == null)
            {
                return(null);
            }
            else
            {
                return(P.X.ToByteArray());
            }
        }
Exemple #6
0
        /// <summary>
        /// Creates one eliptic curve point using x coordinate.
        /// If there is no point with x coordinate null is returned.
        /// </summary>
        /// <param name="x">the x coordinate of point</param>
        /// <returns>Found point or null.</returns>
        public ElipticCurvePoint FindPointByX(BigInteger x)
        {
            //BigInteger ySquare = x.ModPow(3, curve.P).ModAdd(x.ModMul(curve.A, curve.P), curve.P).ModAdd(curve.B, curve.P);
            BigInteger ySquare = (BigInteger.ModPow(x, 3, curve.P) + curve.A * x + curve.B).Mod(curve.P);
            //BigInteger yRoot = ySquare.ModPow((curve.P + 1) / 4, curve.P);
            BigInteger        yRoot  = BigInteger.ModPow(ySquare, (curve.P + 1) / 4, curve.P);
            ElipticCurvePoint result = new ElipticCurvePoint(x, yRoot);

            if (IsCurvePoint(result))
            {
                return(result);
            }
            else
            {
                return(null);
            }
        }
Exemple #7
0
        /// <summary>
        /// multiplies eliptic curve point X times. Optimised algorhytm.
        /// </summary>
        /// <param name="times">multiplier</param>
        /// <param name="point">liptic curve point</param>
        /// <returns>multiplied eliptic curve point</returns>
        internal ElipticCurvePoint Multiply(BigInteger times, ElipticCurvePoint point)
        {
            if (times == 0)
            {
                return(null);
            }
            if (times == 1)
            {
                return(point);
            }
            ElipticCurvePoint splited = Multiply(times / 2, point);
            ElipticCurvePoint added   = Add(splited, splited);

            if (!times.IsEven)
            {
                added = Add(added, point);
            }
            return(added);
        }
Exemple #8
0
        /// <summary>
        /// adds 2 eliptic curve point
        /// </summary>
        /// <param name="p">point 1</param>
        /// <param name="q">point 2</param>
        /// <returns>eliptic curve point or null if identitt element O</returns>
        public ElipticCurvePoint Add(ElipticCurvePoint p, ElipticCurvePoint q)
        {
            if (p == null)
            {
                return(q);
            }
            if (q == null)
            {
                return(p);
            }
            if (AreInverse(p, q))
            {
                return(null);
            }

            BigInteger xr;
            BigInteger yr;
            BigInteger s;

            if (p.Equals(q))
            {
                //s = p.X.ModPow(2, curve.P).ModMul(3, curve.P).ModAdd(curve.A, curve.P).ModDiv(p.Y.ModMul(2, curve.P), curve.P);
                s = (BigInteger.ModPow(p.X, 2, curve.P) * 3 + curve.A).ModDiv(p.Y * 2, curve.P);
                //xr = s.ModPow(2, curve.P).ModSub(p.X, curve.P).ModSub(p.X, curve.P);
                xr = (BigInteger.ModPow(s, 2, curve.P) - p.X - p.X).Mod(curve.P);
                //yr = s.ModMul(p.X.ModSub(xr, curve.P), curve.P).ModSub(p.Y, curve.P);
                yr = (s * (p.X - xr) - p.Y).Mod(curve.P);
            }
            else
            {
                s = (q.Y.ModSub(p.Y, curve.P)).ModDiv(q.X.ModSub(p.X, curve.P), curve.P);
                //s = (q.Y - p.Y).ModDiv((q.X - p.X), curve.P); not working
                //xr = s.ModPow(2, curve.P).ModSub(p.X, curve.P).ModSub(q.X, curve.P);
                xr = (BigInteger.ModPow(s, 2, curve.P) - p.X - q.X).Mod(curve.P);
                //yr = s.ModMul(p.X.ModSub(xr, curve.P), curve.P).ModSub(p.Y, curve.P);
                yr = (s * (p.X - xr) - p.Y).Mod(curve.P);
            }
            return(new ElipticCurvePoint(xr, yr));
        }
Exemple #9
0
        /// <summary>
        /// serialises ec point into byte array over specified eliptic curve.
        /// first byte value meaning:
        /// 0x00 - zero point
        /// 0x04 - uncomprimed
        /// 0x02 - comprimed with even Y
        /// 0x03 - comprimed with odd Y
        /// </summary>
        /// <param name="point">point to serialise</param>
        /// <param name="comprimend">serialised point</param>
        /// <returns></returns>
        public byte[] SerialisePoint(ElipticCurvePoint point, bool comprimend)
        {
            int size = curve.P.ToByteArray().Length;

            if (comprimend)
            {
                byte[] result = new byte[1 + size];
                if (point == null)
                {
                    return(result);
                }
                byte[] xBytes = point.X.ToByteArray();
                if (point.Y.IsEven)
                {
                    result[0] = 0x02;
                }
                else
                {
                    result[0] = 0x03;
                }
                Buffer.BlockCopy(xBytes, 0, result, 1, xBytes.Length);
                return(result);
            }
            else
            {
                byte[] result = new byte[1 + size * 2];
                if (point == null)
                {
                    return(result);
                }
                byte[] xBytes = point.X.ToByteArray();
                byte[] yBytes = point.Y.ToByteArray();
                result[0] = 0x04;
                Buffer.BlockCopy(xBytes, 0, result, 1, xBytes.Length);
                Buffer.BlockCopy(yBytes, 0, result, 1 + size, yBytes.Length);
                return(result);
            }
        }
Exemple #10
0
        /// <summary>
        /// Decrypts cipherText in plainText
        /// </summary>
        /// <param name="cipher">cipher text</param>
        /// <param name="privateKey">private key</param>
        /// <returns>original plain text</returns>
        public string Decrypt(byte[] cipher, byte[] privateKey, Encoding enc, bool comprimed = false)
        {
            BigInteger pk          = new BigInteger(privateKey);
            int        encByteSize = enc.GetBytes("a").Length;
            int        M           = ((curve.BitSize / 8) - 1) / encByteSize * encByteSize;
            int        N           = curve.BitSize / 8 - M;

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

            ElipticCurvePoint[] points = serialiser.DeserielisePoints(cipher, comprimed).ToArray();
            for (int i = 0; i < points.Count(); i += 2)
            {
                ElipticCurvePoint C1 = points[i];
                ElipticCurvePoint C2 = points[i + 1];
                ElipticCurvePoint m  = calculator.Add(C2, calculator.Inverse(calculator.Multiply(pk, C1)));
                xByte.AddRange(m.X.ToByteArray().Skip(N));
                while (xByte.Count % encByteSize != 0)
                {
                    xByte.Add(0);
                }
            }
            return(enc.GetString(xByte.ToArray()));
        }
Exemple #11
0
        /// <summary>
        /// Creates signature to specified file using private key
        /// </summary>
        /// <param name="file">File to sign</param>
        /// <param name="privateKey">private key</param>
        /// <returns></returns>
        public byte[] Signature(string message, byte[] privateKey)
        {
            BigInteger hash = new BigInteger(HashMessage(message));
            BigInteger r, s;
            BigInteger pk = new BigInteger(privateKey);

            do
            {
                BigInteger        k    = rnd.Next(1, curve.N - 1);
                ElipticCurvePoint x1y1 = calculator.Multiply(k, curve.G);
                r = x1y1.X.Mod(curve.N);
                //s = ((BigInteger)k.ModInv(curve.N)).ModMul(hash.ModAdd(privateKey.ModMul(r, curve.N), curve.N), curve.N);
                s = (((BigInteger)k.ModInv(curve.N)) * (hash + pk * r)).Mod(curve.N);
            } while (r == 0 || s == 0);

            int size = curve.N.ToByteArray().Length;

            byte[] result = new byte[size * 2];
            byte[] rBytes = r.ToByteArray();
            byte[] sBytes = s.ToByteArray();
            Buffer.BlockCopy(rBytes, 0, result, 0, rBytes.Length);
            Buffer.BlockCopy(sBytes, 0, result, size, sBytes.Length);
            return(result);
        }
Exemple #12
0
        /// <summary>
        /// Deserialise ec point over specified eliptic curve
        /// </summary>
        /// <param name="bytes">serialised point</param>
        /// <returns>deserialised point</returns>
        internal ElipticCurvePoint DeserialisePoint(byte[] bytes)
        {
            //this is error
            if (bytes == null)
            {
                throw new InvalidPointFormatException("Cannot convert null to eliptic curve point. Zero point (null) is serialised with prefix 0x00", bytes);
            }
            if (bytes.Length == 0)
            {
                throw new InvalidPointFormatException("Cannot convert empty byte array to eliptic curve point. Zero point (null) is serialised with prefix 0x00", bytes);
            }
            int size = curve.P.ToByteArray().Length;

            //deserialise zero point
            if (bytes[0] == 0x00)
            {
                return(null);
            }
            //deserielse uncomprimed point
            if (bytes[0] == 0x04)
            {
                if (bytes.Length != size * 2 + 1)
                {
                    throw new InvalidPointFormatException($"point serialised over curve {curve.Name} should have {size * 2 + 1} bytes in uncomprimed form.", bytes);
                }
                byte[] xBytes = new byte[size];
                byte[] yBytes = new byte[size];
                Buffer.BlockCopy(bytes, 1, xBytes, 0, size);
                Buffer.BlockCopy(bytes, 1 + size, yBytes, 0, size);
                ElipticCurvePoint point = new ElipticCurvePoint(new BigInteger(xBytes), new BigInteger(yBytes));
                if (!calc.IsCurvePoint(point))
                {
                    throw new InvalidPointFormatException("deserialised point was not found on curve...", bytes);
                }
                return(point);
            }
            //deserialise comprimed point
            else
            {
                if (bytes.Length != size + 1)
                {
                    throw new InvalidPointFormatException($"point serialised over curve {curve.Name} should have {size + 1} bytes in comprimed form.", bytes);
                }
                bool yEven;
                switch (bytes[0])
                {
                case 0x02: yEven = true; break;

                case 0x03: yEven = false; break;

                default: throw new InvalidPointFormatException("First byte of serialised point should be 0x00 for zero point, 0x04 for uncomprimed, 0x02 for comprimed with even Y and 0x03 for comprimed with odd Y.", bytes);
                }
                byte[] xBytes = new byte[size];
                Buffer.BlockCopy(bytes, 1, xBytes, 0, size);
                BigInteger        x     = new BigInteger(xBytes);
                ElipticCurvePoint point = calc.FindPointByX(x);
                if (point == null)
                {
                    throw new InvalidPointFormatException("deserialised point was not found on curve...", bytes);
                }
                if (point.Y.IsEven == yEven)
                {
                    return(point);
                }
                else
                {
                    return(calc.Inverse(point));
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Verifies signature to specified file using public key
        /// </summary>
        /// <param name="file">signed file</param>
        /// <param name="signature">signature</param>
        /// <param name="publicKey">public key</param>
        /// <returns></returns>
        public bool VerifySignature(string message, byte[] signature, byte[] publicKey)
        {
            int size = curve.N.ToByteArray().Length;

            byte[] rBytes = new byte[size];
            byte[] sBytes = new byte[size];
            Buffer.BlockCopy(signature, 0, rBytes, 0, size);
            Buffer.BlockCopy(signature, size, sBytes, 0, size);
            BigInteger r = new BigInteger(rBytes);
            BigInteger s = new BigInteger(sBytes);

            //1. public key point isnt identity element O' and coordinates are valid
            //2. public key point lies on curve (exception is thrown if not)
            ElipticCurvePoint publicKeyPoint = serialiser.DeserialisePoint(publicKey);

            if (publicKeyPoint == null)
            {
                return(false);
            }
            //3. N x publicKey == O
            ElipticCurvePoint zero = calculator.Multiply(curve.N, publicKeyPoint);

            if (zero != null)
            {
                return(false);
            }

            //1. r and s in [1, N-1]
            if (r == 0 || r > curve.N - 1)
            {
                return(false);
            }
            if (s == 0 || s > curve.N - 1)
            {
                return(false);
            }
            //2. calculate hash of message
            BigInteger hash = new BigInteger(HashMessage(message));
            //3. w = 1/s mod N
            BigInteger w = (BigInteger)s.ModInv(curve.N);
            //4. u1 = hash * w mod N
            //   u2 = r * w mod N
            BigInteger u1 = w.ModMul(hash, curve.N);
            BigInteger u2 = w.ModMul(r, curve.N);
            //5. P(x1,y1) = u1 * G + u2 * publicKey mod N
            //   if P(x1,y1) == O => FALSE
            ElipticCurvePoint x1y1 = calculator.Add(calculator.Multiply(u1, curve.G), calculator.Multiply(u2, publicKeyPoint));

            if (x1y1 == null)
            {
                return(false);
            }
            //6. r == x1 mod n => TRUE => ELSE FALSE
            if (r.ModEquals(x1y1.X, curve.N))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #14
0
 /// <summary>
 /// Checks if 2 points are inverse
 /// </summary>
 /// <param name="point1">point 1</param>
 /// <param name="point2">point 2</param>
 /// <returns></returns>
 internal bool AreInverse(ElipticCurvePoint point1, ElipticCurvePoint point2)
 {
     return(point1.X == point2.X && (point1.Y + point2.Y).Mod(curve.P) == 0);
 }
Exemple #15
0
        /// <summary>
        /// compares 2 points
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            ElipticCurvePoint point = (ElipticCurvePoint)obj;

            return(point.X == X && point.Y == Y);
        }