Esempio n. 1
0
        protected virtual ECFieldElement CalculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared)
        {
            ECFieldElement a4 = this.Curve.A;

            if (a4.IsZero)
            {
                return(a4);
            }

            if (ZSquared == null)
            {
                ZSquared = Z.Square();
            }

            ECFieldElement W     = ZSquared.Square();
            ECFieldElement a4Neg = a4.Negate();

            if (a4Neg.BitLength < a4.BitLength)
            {
                W = W.Multiply(a4Neg).Negate();
            }
            else
            {
                W = W.Multiply(a4);
            }
            return(W);
        }
Esempio n. 2
0
        protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
        {
            ECFieldElement x     = FromBigInteger(X1);
            ECFieldElement alpha = x.Square().Add(m_a).Multiply(x).Add(m_b);
            ECFieldElement beta  = alpha.Sqrt();

            //
            // if we can't find a sqrt we haven't got a point on the
            // curve - run!
            //
            if (beta == null)
            {
                throw new ArithmeticException("Invalid point compression");
            }

            if (beta.TestBitZero() != (yTilde == 1))
            {
                // Use the other root
                beta = beta.Negate();
            }

            return(new FpPoint(this, x, beta, true));
        }
Esempio n. 3
0
        // B.3 pg 62
        public override ECPoint Twice()
        {
            if (this.IsInfinity)
            {
                return(this);
            }

            ECCurve curve = this.Curve;

            ECFieldElement Y1 = this.RawYCoord;

            if (Y1.IsZero)
            {
                return(curve.Infinity);
            }

            int coord = curve.CoordinateSystem;

            ECFieldElement X1 = this.RawXCoord;

            switch (coord)
            {
            case ECCurve.COORD_AFFINE:
            {
                ECFieldElement X1Squared = X1.Square();
                ECFieldElement gamma     = Three(X1Squared).Add(this.Curve.A).Divide(Two(Y1));
                ECFieldElement X3        = gamma.Square().Subtract(Two(X1));
                ECFieldElement Y3        = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1);

                return(new FpPoint(Curve, X3, Y3, IsCompressed));
            }

            case ECCurve.COORD_HOMOGENEOUS:
            {
                ECFieldElement Z1 = this.RawZCoords[0];

                bool Z1IsOne = Z1.IsOne;

                // TODO Optimize for small negative a4 and -3
                ECFieldElement w = curve.A;
                if (!w.IsZero && !Z1IsOne)
                {
                    w = w.Multiply(Z1.Square());
                }
                w = w.Add(Three(X1.Square()));

                ECFieldElement s   = Z1IsOne ? Y1 : Y1.Multiply(Z1);
                ECFieldElement t   = Z1IsOne ? Y1.Square() : s.Multiply(Y1);
                ECFieldElement B   = X1.Multiply(t);
                ECFieldElement _4B = Four(B);
                ECFieldElement h   = w.Square().Subtract(Two(_4B));

                ECFieldElement _2s        = Two(s);
                ECFieldElement X3         = h.Multiply(_2s);
                ECFieldElement _2t        = Two(t);
                ECFieldElement Y3         = _4B.Subtract(h).Multiply(w).Subtract(Two(_2t.Square()));
                ECFieldElement _4sSquared = Z1IsOne ? Two(_2t) : _2s.Square();
                ECFieldElement Z3         = Two(_4sSquared).Multiply(s);

                return(new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed));
            }

            case ECCurve.COORD_JACOBIAN:
            {
                ECFieldElement Z1 = this.RawZCoords[0];

                bool Z1IsOne = Z1.IsOne;

                ECFieldElement Y1Squared = Y1.Square();
                ECFieldElement T         = Y1Squared.Square();

                ECFieldElement a4    = curve.A;
                ECFieldElement a4Neg = a4.Negate();

                ECFieldElement M, S;
                if (a4Neg.ToBigInteger().Equals(BigInteger.ValueOf(3)))
                {
                    ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square();
                    M = Three(X1.Add(Z1Squared).Multiply(X1.Subtract(Z1Squared)));
                    S = Four(Y1Squared.Multiply(X1));
                }
                else
                {
                    ECFieldElement X1Squared = X1.Square();
                    M = Three(X1Squared);
                    if (Z1IsOne)
                    {
                        M = M.Add(a4);
                    }
                    else if (!a4.IsZero)
                    {
                        ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square();
                        ECFieldElement Z1Pow4    = Z1Squared.Square();
                        if (a4Neg.BitLength < a4.BitLength)
                        {
                            M = M.Subtract(Z1Pow4.Multiply(a4Neg));
                        }
                        else
                        {
                            M = M.Add(Z1Pow4.Multiply(a4));
                        }
                    }
                    //S = two(doubleProductFromSquares(X1, Y1Squared, X1Squared, T));
                    S = Four(X1.Multiply(Y1Squared));
                }

                ECFieldElement X3 = M.Square().Subtract(Two(S));
                ECFieldElement Y3 = S.Subtract(X3).Multiply(M).Subtract(Eight(T));

                ECFieldElement Z3 = Two(Y1);
                if (!Z1IsOne)
                {
                    Z3 = Z3.Multiply(Z1);
                }

                // Alternative calculation of Z3 using fast square
                //ECFieldElement Z3 = doubleProductFromSquares(Y1, Z1, Y1Squared, Z1Squared);

                return(new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed));
            }

            case ECCurve.COORD_JACOBIAN_MODIFIED:
            {
                return(TwiceJacobianModified(true));
            }

            default:
            {
                throw new InvalidOperationException("unsupported coordinate system");
            }
            }
        }