private static (Fp12 numerator, Fp12 denominator) LineFunction(FpVector3 <Fp12> p1, FpVector3 <Fp12> p2, FpVector3 <Fp12> t) { // As mentioned in py_ecc: the projective coordinates given are (x / z, y / z). // For slope of a line m, we usually have delta_y / delta_x. In this case it would be // m = ((p2.y / p2.z) - (p1.y / p1.z)) / ((p2.x / p2.z) - (p1.x / p1.z)) // So to eliminate these fractions, we multiply both numerator and denominator by p1.z * p2.z, // which yields the values below. This only affects scale but keeps the same m result. Fp12 slopeNumerator = (p2.Y * p1.Z) - (p1.Y * p2.Z); Fp12 slopeDenominator = (p2.X * p1.Z) - (p1.X * p2.Z); // Determine how to compute our data. bool denominatorIsZero = slopeDenominator == Fp12.ZeroValue; bool numeratorIsZero = slopeNumerator == Fp12.ZeroValue; if (denominatorIsZero && !numeratorIsZero) { // Slope is undefined. return((t.X * p1.Z) - (p1.X * t.Z), p1.Z *t.Z); } else if (numeratorIsZero) { slopeNumerator = 3 * p1.X * p1.X; slopeDenominator = 2 * p1.Y * p1.Z; } Fp12 resultNumerator = (slopeNumerator * ((t.X * p1.Z) - (p1.X * t.Z))) - (slopeDenominator * ((t.Y * p1.Z) - (p1.Y * t.Z))); Fp12 resultDenominator = slopeDenominator * t.Z * p1.Z; return(resultNumerator, resultDenominator); }
public static FpVector3 <Fp12> Twist(FpVector3 <Fp2> point) { // If the point isn't properly initialize if (point == null) { return(null); } // Place the items at the start and half way point BigInteger[] xcoefficients = new BigInteger[12] { point.X.Coefficients.ElementAt(0) - (point.X.Coefficients.ElementAt(1) * 9), 0, 0, 0, 0, 0, point.X.Coefficients.ElementAt(1), 0, 0, 0, 0, 0 }; BigInteger[] ycoefficients = new BigInteger[12] { point.Y.Coefficients.ElementAt(0) - (point.Y.Coefficients.ElementAt(1) * 9), 0, 0, 0, 0, 0, point.Y.Coefficients.ElementAt(1), 0, 0, 0, 0, 0 }; BigInteger[] zcoefficients = new BigInteger[12] { point.Z.Coefficients.ElementAt(0) - (point.Z.Coefficients.ElementAt(1) * 9), 0, 0, 0, 0, 0, point.Z.Coefficients.ElementAt(1), 0, 0, 0, 0, 0 }; // Instantiate fp12s from the extended fp2 Fp12 newx = new Fp12(xcoefficients); Fp12 newy = new Fp12(ycoefficients); Fp12 newz = new Fp12(zcoefficients); // Return a twisted point from fp2 to fp12. return(new FpVector3 <Fp12>(newx * _twistPoint.Pow(2), newy * _twistPoint.Pow(3), newz)); }
private static Fp12 MillerLoop(FpVector3 <Fp12> q, FpVector3 <Fp12> p, bool finalExponentiate = true) { if (q == null || p == null) { return(Fp12.OneValue); } FpVector3 <Fp12> nq = q.Negate(); FpVector3 <Fp12> r = (FpVector3 <Fp12>)q.Clone(); Fp12 fNumerator = Fp12.OneValue; Fp12 fDenominator = Fp12.OneValue; for (int i = LogAteLoopCount; i >= 0; i--) { (Fp12 num, Fp12 denom) = LineFunction(r, r, p); fNumerator = fNumerator * fNumerator * num; fDenominator = fDenominator * fDenominator * denom; r = r.Double(); int v = PseudoBinaryEncoding[i]; if (v == 1) { (num, denom) = LineFunction(r, q, p); fNumerator *= num; fDenominator *= denom; r = r.Add(q); } else if (v == -1) { (num, denom) = LineFunction(r, nq, p); fNumerator *= num; fDenominator *= denom; r = r.Add(nq); } } FpVector3 <Fp12> q1 = new FpVector3 <Fp12>(q.X.Pow(Bn128Curve.P), q.Y.Pow(Bn128Curve.P), q.Z.Pow(Bn128Curve.P)); FpVector3 <Fp12> nq2 = new FpVector3 <Fp12>(q1.X.Pow(Bn128Curve.P), -q1.Y.Pow(Bn128Curve.P), q1.Z.Pow(Bn128Curve.P)); (Fp12 num1, Fp12 denom1) = LineFunction(r, q1, p); r = r.Add(q1); (Fp12 num2, Fp12 denom2) = LineFunction(r, nq2, p); Fp12 f = (fNumerator * num1 * num2) / (fDenominator * denom1 * denom2); return(finalExponentiate ? FinalExponentiate(f) : f); }
/// <summary> /// Our default static constructor, sets static read only variables. /// </summary> static Bn128Curve() { N = BigInteger.Parse("21888242871839275222246405745257275088548364400416034343698204186575808495617", CultureInfo.InvariantCulture); P = BigInteger.Parse("21888242871839275222246405745257275088696311157297823662689037894645226208583", CultureInfo.InvariantCulture); _twistPoint = new Fp12(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); G1 = new FpVector3 <Fp>(Fp.OneValue, new Fp(2), Fp.OneValue); G2 = new FpVector3 <Fp2>( new Fp2( BigInteger.Parse("10857046999023057135944570762232829481370756359578518086990519993285655852781", CultureInfo.InvariantCulture), BigInteger.Parse("11559732032986387107991004021392285783925812861821192530917403151452391805634", CultureInfo.InvariantCulture)), new Fp2( BigInteger.Parse("8495653923123431417604973247489272438418190587263600148770280649306958101930", CultureInfo.InvariantCulture), BigInteger.Parse("4082367875863433681332203403145435568316851327593401208105741076214120093531", CultureInfo.InvariantCulture)), Fp2.OneValue); B = new Fp(3); B2 = new Fp2(3, 0) / new Fp2(9, 1); B12 = new Fp12(3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); }
public static Fp12 FinalExponentiate(Fp12 p) { return(p.Pow((BigInteger.Pow(Bn128Curve.P, 12) - 1) / Bn128Curve.N)); }