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)); }
public static Fp12 Pair(FpVector3 <Fp2> q, FpVector3 <Fp> p, bool finalExponentiate = true) { // Check z's for zero. if (p.Z == Fp.ZeroValue || q.Z == Fp2.ZeroValue) { return(Fp12.OneValue); } // Run the miller loop on twist(q) and fq12(p) return(MillerLoop(Bn128Curve.Twist(q), CastFpPointToFp12Point(p), finalExponentiate)); }
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); }
private static FpVector3 <Fp12> CastFpPointToFp12Point(FpVector3 <Fp> point) { // If our point isn't initialized, return null. if (point == null) { return(null); } // Create our data for our fq BigInteger[] xData = new BigInteger[12]; xData[0] = point.X.N; BigInteger[] yData = new BigInteger[12]; yData[0] = point.Y.N; BigInteger[] zData = new BigInteger[12]; zData[0] = point.Z.N; // Return our Fp12 vector. return(new FpVector3 <Fp12>(new Fp12(xData), new Fp12(yData), new Fp12(zData))); }
public FpVector3 <T> Add(FpVector3 <T> p2) { // Verify our z coordinates aren't zero if (p2.Z.Equals(X.Zero)) { return(this); } else if (Z.Equals(X.Zero)) { return(p2); } T u1 = p2.Y.Multiply(Z); T u2 = Y.Multiply(p2.Z); T v1 = p2.X.Multiply(Z); T v2 = X.Multiply(p2.Z); if (v1.Equals(v2) && u1.Equals(u2)) { return(Double()); } else if (v1.Equals(v2)) { return(new FpVector3 <T>(X.One, X.One, X.Zero)); } T u = u1.Subtract(u2); T v = v1.Subtract(v2); T v_sq = v.Multiply(v); T v_sq_v2 = v_sq.Multiply(v2); T v_cu = v_sq.Multiply(v); T w = Z.Multiply(p2.Z); T a = u.Multiply(u).Multiply(w).Subtract(v_cu).Subtract(v_sq_v2.Multiply(2)); T newx = v.Multiply(a); T newy = u.Multiply(v_sq_v2.Subtract(a)).Subtract(v_cu.Multiply(u2)); T newz = v_cu.Multiply(w); return(new FpVector3 <T>(newx, newy, newz)); }