예제 #1
0
        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);
        }
예제 #2
0
        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));
        }
예제 #3
0
        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);
        }
예제 #4
0
 /// <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);
 }
예제 #5
0
 public static Fp12 FinalExponentiate(Fp12 p)
 {
     return(p.Pow((BigInteger.Pow(Bn128Curve.P, 12) - 1) / Bn128Curve.N));
 }