//--------------------------------------------------------------
        // Recovering secret by some shades
        // for theoretical GO TO WIKIPEDIA, reference - shamir secret sharing, lagrange interpolation
        //--------------------------------------------------------------
        private BigInteger deShamir(Dictionary <BigInteger, BigInteger> kv_pairs, BigInteger p)
        {
            int k = kv_pairs.Count;

            BigInteger secret    = new BigInteger(0);
            BigInteger high_part = new BigInteger(1);   // high part of lagrange intepolation
            BigInteger low_part  = new BigInteger(1);   // low part of lagrange interpolation

            // first_kv - shade number 1
            // second_kv - shade number 2
            foreach (KeyValuePair <BigInteger, BigInteger> first_kv in kv_pairs)
            {
                foreach (KeyValuePair <BigInteger, BigInteger> second_kv in kv_pairs)
                {
                    if (first_kv.Key != second_kv.Key)
                    {
                        high_part = high_part * ((-1) * second_kv.Key);        // -1 caused that we need x - xj, but our x = 0, that now (-xj)
                        low_part  = low_part * (first_kv.Key - second_kv.Key); // calculate low part
                    }
                }

                // Lagrange interpolation have division, but we need only integer numbers, so
                //  a * a^(-1) = 1
                // but we can make some fun and:
                //  a * a^(-1) = 1 (mod p)
                // so, when we have modulo, we can change a^(-1) to another number, that give us similar result ^.^
                //  a * b = 1 (mod p).
                // b can be calculated by Evklid algorithm in form 'ax + by = gcd(a,b)'  (*1)
                // so we set 2 numbers, a = low_part and b = p, and gets gcd and 2 numbers, x and y.
                // We know that gcd(prime_number, any_number) = 1, so change (*1) to our rules:
                // low_part * x + p*y = 1
                // In this form y always be the '0' (ave MATH!), so we get
                // low_part*x = 1
                // where x - our (low_part)^(-1)
                // MAGIIIIIIIIIIC!
                iVector temp = Evklid(low_part, p);

                low_part = MathMod(temp.y, p);

                high_part = MathMod((high_part * low_part), p); // let high part temporary storage all lart of 'li' (see lagrange interpolation)

                secret   += high_part * first_kv.Value;         // summ_all( y * li )
                high_part = 1;
                low_part  = 1;
            }
            secret = MathMod(secret, p); // Let restrict out sercet by out square.
            return(secret);              // Done. You are delicious ^_^
        }
        public iVector Evklid(BigInteger a, BigInteger b)
        {
            iVector    u = new iVector(a, 1, 0);
            iVector    v = new iVector(b, 0, 1);
            iVector    T = new iVector(0, 0, 0);
            BigInteger q = 0;

            while (v.x != 0)
            {
                q = u.x / v.x;

                T.x = MathMod(u.x, v.x);

                T.y = u.y - q * v.y;
                T.z = u.z - q * v.z;

                u.set(v); // u = v, but we need to CHANGE value, not CHANGE POINTER.
                v.set(T); // u = v, but we need to CHANGE value, not CHANGE POINTER.
            }

            return(u);
        }
 public void set(iVector sec)
 {
     this.x = sec.x;
     this.y = sec.y;
     this.z = sec.z;
 }