Exemple #1
0
        //https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates#Mixed_Addition_(with_affine_point)_(8M_+_3S)
        //U1 = X1  [*Z2^2]
        //U2 = X2*Z1^2
        //S1 = Y1  [*Z2^3]
        //S2 = Y2*Z1^3
        //if (U1 == U2)
        //  if (S1 != S2)
        //    return POINT_AT_INFINITY
        //  else
        //    return POINT_DOUBLE(X1, Y1, Z1)
        //H = U2 - U1
        //R = S2 - S1
        //X3 = R^2 - H^3 - 2*U1*H^2
        //Y3 = R*(U1*H^2 - X3) - S1*H^3
        //Z3 = H*Z1*Z2
        //return (X3, Y3, Z3)

        //http://www.hyperelliptic.org/EFD/oldefd/jacobian.html#mADD
        //Z2 = [p.Z]^2
        //S1 = [q.X] * Z2 - [p.X]
        //R1 = [+/-q.Y] * [p.Z] * Z2 - [p.Y]
        //S2 = S1^2
        //Z3 = ([p.Z]+S1)^2 - S2 - Z2
        //S2 *= 4
        //S1 *= S2
        //R1 = 2*R1
        //Y3 = [p.X]*S2
        //X3 = R1^2-S1-2*Y3
        //Y3 = R1*(Y3-X3)-2*[p.y]*S1
        public void Add(ref JacobianECPoint p, OwnECPoint q, bool subtract = false)
        {   //Mixed addition returns p + q in "7M + 4S"
            if (p.IsInfinity || q.IsInfinity)
            {
                if (!q.IsInfinity)
                {
                    p.SetFrom(q.X, q.Y, One, q.IsInfinity);
                    if (subtract)
                    {
                        SubtractModP(P, p.Y, p.Y);
                    }
                }
                return;
            }

            Let(Z2, p.Z); SquareModP(Z2);                         //Z2 = [p.Z]^2
            Let(S1, q.X); MultiplyModP(S1, Z2); SubModP(S1, p.X); //S1 = [q.X] * Z2 - [p.X]
            Let(R1, q.Y);
            if (subtract)
            {
                SubtractModP(P, R1, R1);
            }
            MultiplyModP(R1, p.Z); MultiplyModP(R1, Z2); SubModP(R1, p.Y);   //R1 = [+/-q.Y] * [p.Z] * Z2 - [p.Y]

            if (IsZero(S1))
            {
                if (IsZero(R1))
                {   //now: p == q
                    GetDouble(ref p);
                    return;
                }
                p.SetInfinity();
                return;
            }

            Let(S2, S1); SquareModP(S2);                                                            //S2 = S1^2
            Let(Z3, p.Z); AddModP(Z3, S1); SquareModP(Z3); SubModP(Z3, S2); SubModP(Z3, Z2);        //Z3 = ([p.Z]+S1)^2 - S2 - Z2

            AddScaledModP(S2, S2, 3);                                                               //S2 *= 4
            MultiplyModP(S1, S2);                                                                   //S1 *= S2
            AddModP(R1, R1);                                                                        //R1 = 2*R1
            Let(y1, p.X); MultiplyModP(y1, S2);                                                     //Y3 = [p.X]*S2
            Let(x1, R1); SquareModP(x1); SubModP(x1, S1); SubScaledModP(x1, y1, 2);                 //X3 = R1^2-S1-2*Y3
            MultiplyModP(S1, p.Y); SubModP(y1, x1); MultiplyModP(y1, R1); SubScaledModP(y1, S1, 2); //Y3 = R1*(Y3-X3)-2*[p.y]*S1

            p.SetFrom(x1, y1, Z3, false);
        }
Exemple #2
0
        public void GetDouble(ref JacobianECPoint p)
        {   //return: 2 * p in "3M + 4S" for a = 0 and "3M + 5S" for a = -3.
            if (p.IsInfinity)
            {
                return;
            }
            if (IsZero(p.Y))
            {
                p.SetInfinity();
                return;
            }

            if (AIsZero)
            {
                //https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates
                //if (Y == 0)
                //  return POINT_AT_INFINITY
                //S = 4 * X * Y^2
                //M = 3*X^2 [+ a* Z^4]
                //X' = M^2 - 2*S
                //Y' = M*(S - X') - 8*Y^4
                //Z' = 2*Y*Z = (Y+Z)^2 - Y^2 - Z^2
                //return (X', Y', Z')
                Let(R1, p.Y); SquareModP(R1); AddModP(R1, R1);                                //R1 = 2 * Y^2
                Let(Z3, R1); SquareModP(Z3);                                                  //Z3 = 4 * Y^4
                Let(S1, p.X); MultiplyModP(S1, R1); AddModP(S1, S1);                          //S1 = S = 4 * X * Y^2

                Let(S2, p.X); SquareModP(S2); AddScaledModP(S2, S2, 2);                       //S2 = M = 3*X^2 [+ a* Z^4]   because a == 0.

                Let(x1, S2); SquareModP(x1); SubScaledModP(x1, S1, 2);                        //X' = M^2 - 2*S
                Let(y1, S1); SubModP(y1, x1); MultiplyModP(y1, S2); SubScaledModP(y1, Z3, 2); //Y' = M*(S - X') - 8*Y^4
                Let(Z3, p.Y); AddModP(Z3, Z3); MultiplyModP(Z3, p.Z);                         //Z' = 2*Y*Z

                p.SetFrom(x1, y1, Z3, false);
            }
            else if (AIsMinus3)
            {
                //http://www.hyperelliptic.org/EFD/oldefd/jacobian.html#a3DBL
                //delta:=Z1^2;
                //gamma:=Y1^2;
                //beta:=4*X1*gamma;
                //alpha:=3*(X1-delta)*(X1+delta);
                //X3:=alpha^2-2*beta;
                //Z3:=(Y1+Z1)^2-gamma-delta;
                //Y3:=alpha*(beta-X3)-8*gamma^2;
                Let(Z2, p.Z); SquareModP(Z2);                                 //Z2:= delta:=Z1^2;
                Let(y1, p.Y); SquareModP(y1);                                 //y1:= gamma:=Y1^2;
                Let(R1, p.X); MultiplyModP(R1, y1); AddScaledModP(R1, R1, 3); //R1:= beta:=4*X1*gamma;

                SubtractModP(p.X, Z2, S1);
                AdditionModP(p.X, Z2, S2);
                MultiplyModP(S1, S2);
                AddScaledModP(S1, S1, 2);                                                        //S1:= alpha:=3*(X1-delta)*(X1+delta)       because a == -3

                AddModP(Z2, y1);                                                                 //delta = delta + gamma
                Let(x1, S1); SquareModP(x1); SubScaledModP(x1, R1, 2);                           //X3:= alpha^2-2*beta;
                Let(Z3, p.Y); AddModP(Z3, p.Z); SquareModP(Z3); SubModP(Z3, Z2);                 //Z3 = (Y1+Z1)^2-delta
                SubModP(R1, x1); MultiplyModP(R1, S1); SquareModP(y1); SubScaledModP(R1, y1, 8); //Y3 = alpha*(beta-X3)-8*gamma^2

                p.SetFrom(x1, R1, Z3, false);
            }
            else
            {
                throw new NotImplementedException();
            }
        }