Ejemplo n.º 1
0
        /// <summary>
        /// Dencrypt text on elliptic curve and return the message
        /// </summary>
        /// <param name="LstEncr"></param>
        /// <param name="SecretKey"></param>
        /// <returns></returns>
        public static string EcDecrypt(List <EcModPoint> LstEncr, BigInteger SecretKey, EllipticCurveType EcType)
        {
            BigInteger p;
            BigInteger n;
            BigInteger a;
            BigInteger b;

            // Set params
            switch (EcType)
            {
            case EllipticCurveType.SEC256K1:
                p = SEC256K1_P;
                n = SEC256K1_N;
                a = SEC256K1_A;
                b = SEC256K1_B;
                break;

            case EllipticCurveType.M383:
                p = M383_P;
                n = M383_N;
                a = M383_A;
                b = M383_B;
                break;

            case EllipticCurveType.E521:
                p = E521_P;
                n = E521_N;
                a = E521_A;
                b = E521_B;
                break;

            default:
                break;
            }

            // 1) get kG
            var kG = LstEncr.First();
            // 2) compute kPb = k(SkG) = Sk(kG)
            var kPb = ECKeyPairGenerator(p, a, b, kG, n, SecretKey);
            // set -kPb
            var negkPb = new EcModPoint {
                x = kPb.x, y = -kPb.y
            };

            // remove kG from the list
            LstEncr.RemoveAt(0);

            // 3) decrypt - compute Pc - kPb = Pm (plain message)
            var strMsg = string.Empty;

            foreach (var pnt in LstEncr)
            {
                var decPnt = pointAdd(pnt, negkPb, p);
                // data from x coord
                var arrUShort = Base65536Helper.ToArray(decPnt.x);
                var bytes     = arrUShort.ToByteArray();
                var str       = Encoding.Unicode.GetString(bytes);
                strMsg = string.Concat(strMsg, str);
                // data from y coord
                arrUShort = Base65536Helper.ToArray(decPnt.y);
                bytes     = arrUShort.ToByteArray();
                str       = Encoding.Unicode.GetString(bytes);
                strMsg    = string.Concat(strMsg, str);
            }

            return(strMsg);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Encrypt text on elliptic curve and return a list of points on the elliptic curve
        /// </summary>
        /// <param name="Text"></param>
        /// <param name="PubKey"></param>
        /// <returns></returns>
        public static List <EcModPoint> EcEncrypt(string Text, EcModPoint PubKey, EllipticCurveType EcType)
        {
            BigInteger p;
            BigInteger n;
            BigInteger a;
            BigInteger b;

            // Set params
            switch (EcType)
            {
            case EllipticCurveType.SEC256K1:
                p = SEC256K1_P;
                n = SEC256K1_N;
                a = SEC256K1_A;
                b = SEC256K1_B;
                break;

            case EllipticCurveType.M383:
                p = M383_P;
                n = M383_N;
                a = M383_A;
                b = M383_B;
                break;

            case EllipticCurveType.E521:
                p = E521_P;
                n = E521_N;
                a = E521_A;
                b = E521_B;
                break;

            default:
                break;
            }

            // return the digits of P base 65536
            ushort[] digits       = Base65536Helper.ToArray(p);
            var      partitionLen = digits.Length - 1;

            // return a string array with string spit in groups of digits
            var partitionStrings = Text.SplitInGroup(partitionLen);

            // 1) create a list of big integers out of partitioned message
            List <BigInteger> lstBiMsg = new List <BigInteger>();

            foreach (var partitionStr in partitionStrings)
            {
                // encode the partioned str in Unicode
                var encUtf8 = Encoding.Unicode.GetBytes(partitionStr);
                // convert to ushort array
                var arrShort = encUtf8.ToUShortArray();
                // convert to Base 65536 big integer
                var bi65536 = Base65536Helper.FromArray(arrShort);
                // add to the list
                lstBiMsg.Add(bi65536);
            }

            // 2) pair with ascii 32 (space) if list count is odd
            var lstCnt = lstBiMsg.Count;

            if (0 != lstCnt % 2)
            {
                lstBiMsg.Add(32);
                lstCnt++;
            }
            // 3) build the pairs
            List <EcModPoint> lstPm = new List <EcModPoint>();

            for (int i = 0; i < lstCnt; i += 2)
            {
                var pnt = new EcModPoint {
                    x = lstBiMsg[i], y = lstBiMsg[i + 1]
                };
                lstPm.Add(pnt);
            }

            // get a random big integer k
            var k = BigIntegerExtensions.NextBigInteger(185, DateTime.Now.Millisecond);
            // 4) compute k*G for the chosen curve
            EcModPoint kG = null;

            switch (EcType)
            {
            case EllipticCurveType.SEC256K1:
                kG = SecP256k1KeyPairGenerator(k);
                break;

            case EllipticCurveType.M383:
                kG = M383KeyPairGenerator(k);
                break;

            case EllipticCurveType.E521:
                kG = E521KeyPairGenerator(k);
                break;

            default:
                break;
            }

            // 5) compute kPb = k(SkG)
            var kPb = ECKeyPairGenerator(p, a, b, PubKey, n, k);

            // 6) compute Pm + kPb = Pc (encrypted data)
            List <EcModPoint> lstEncr = new List <EcModPoint>();

            // first row is kG
            lstEncr.Add(kG);
            foreach (var pnt in lstPm)
            {
                var pntAdded = pointAdd(pnt, kPb, p);
                lstEncr.Add(pntAdded);
            }

            return(lstEncr);
        }