public T Multiply(T other) { // Create an extended list which can contain results from both coefficient collections. List <BigInteger> b = new List <BigInteger>(new BigInteger[(Degree * 2) - 1]); // Compute each product linearly for every index in our list. for (int i = 0; i < Coefficients.Count; i++) { for (int j = 0; j < other.Coefficients.Count; j++) { b[i + j] += Coefficients.ElementAt(i) * other.Coefficients.ElementAt(j); } } for (int exp = Degree - 2; exp >= 0; exp--) { BigInteger top = b[b.Count - 1]; b.RemoveAt(b.Count - 1); for (int i = 0; i < ModulusCoefficients.Count; i++) { b[exp + i] -= top * ModulusCoefficients.ElementAt(i); } } // Perform modular division to wrap our coefficients around p. return(New(b.Select(x => x.Mod(Bn128Curve.P)))); }
public T Inverse() { // Define our initial variables and give them their initial assignments. BigInteger[] newt = new BigInteger[Degree + 1]; newt[0] = 1; BigInteger[] t = new BigInteger[Degree + 1]; BigInteger[] newr = new BigInteger[Coefficients.Count + 1]; Coefficients.CopyTo(newr, 0); BigInteger[] r = new BigInteger[ModulusCoefficients.Count + 1]; ModulusCoefficients.CopyTo(r, 0); r[r.Length - 1] = 1; // Loop while there are elements which are non-zero. while (GetDegree(newr) != 0) { BigInteger[] quotient = DividePolynomialRounded(r, newr); Array.Resize(ref quotient, Degree + 1); BigInteger[] tempt = (BigInteger[])t.Clone(); BigInteger[] tempr = (BigInteger[])r.Clone(); for (int i = 0; i < Degree + 1; i++) { for (int j = 0; j < Degree + 1 - i; j++) { tempt[i + j] -= newt[i] * quotient[j]; tempr[i + j] -= newr[i] * quotient[j]; } } // Perform modulo on tempt for (int i = 0; i < tempt.Length; i++) { tempt[i] = tempt[i].Mod(Bn128Curve.P); } // Perform modulo on tempr for (int i = 0; i < tempr.Length; i++) { tempr[i] = tempr[i].Mod(Bn128Curve.P); } // Swap state for the next iteration. (newt, newr, t, r) = (tempt, tempr, newt, newr); } // Resize the array to the degree size accordingly, divide and return. Array.Resize(ref newt, Degree); return(New(newt).Divide(newr[0])); }