static byte[] CombineNK(KeyShare[] Shares) {
var Threshold = Shares[0].Threshold;
if (Shares.Length < Threshold) throw new Throw("Not Enough Shares");
var Modulus = BigInteger.Pow(2, 129) - 25;
BigInteger Accum = 0;
//Console.WriteLine("Modulus = {0} ", Modulus);
for (var Formula = 0; Formula < Threshold; Formula++) {
var Value = Shares[Formula].Value;
//Console.WriteLine("Value = {0} ", Value);
BigInteger Numerator = 1, Denominator = 1;
for (var Count = 0; Count < Threshold; Count++) {
if (Formula == Count) continue; // If not the same value
var Start = Shares[Formula].Index;
var Next = Shares[Count].Index;
Numerator = (Numerator * -Next) % Modulus;
Denominator = (Denominator * (Start - Next)) % Modulus;
}
var InvDenominator = ModInverse(Denominator, Modulus);
//Console.WriteLine(" Numerator = {0}", Numerator);
//Console.WriteLine(" Denominator = {0}", Denominator);
//Console.WriteLine(" InvDenominator = {0}", InvDenominator);
Accum = (Modulus + Modulus + Accum + (Value * Numerator * InvDenominator)) % Modulus;
if (Accum < 0) {
//Console.WriteLine("Accum = {0}\n", Accum);
}
}
//Console.WriteLine("Accum = {0} ", Accum);
return GetBytes (Accum);
}