public static UInt16 get_secret(UInt16[] shares, UInt32 size)
        {
            UInt32 secret = 0;

            // Calculate numerator
            for (UInt32 i = 0; i < size; ++i)
            {
                UInt32 numerator   = 1;
                UInt32 denominator = 1;
                share  si          = new share(shares[i]);

                for (UInt32 j = 0; j < size; ++j)
                {
                    if (i == j)
                    {
                        continue;
                    }

                    share sj = new share(shares[j]);
                    numerator = mod_math.mod_multiply(numerator, sj.x);
                    UInt32 diff = mod_math.mod_subtract(sj.x, si.x);
                    denominator = mod_math.mod_multiply(diff, denominator);
                }

                UInt32 invert = mod_math.mod_invert(denominator);
                UInt32 ci     = mod_math.mod_multiply(numerator, invert);
                UInt32 tmp    = mod_math.mod_multiply(ci, si.value);
                secret = mod_math.mod_add(secret, tmp);
            }

            return((UInt16)(secret));
        }
        public UInt16[] make_shares(byte secret_byte)
        {
            UInt16[] share_array = new UInt16[_shares];

            init_coefficients();
            _coefficients[(UInt32)(_required) - 1] = secret_byte;

            UInt16 x = 1;

            for (UInt32 i = 0; i < _shares; ++i, ++x)
            {
                share s = new share(x, shared_math.make_share(_coefficients, x));
                share_array[i] = s.to_uint16();
            }

            return(share_array);
        }