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)))); }