예제 #1
0
        public override ECPoint Add(ECPoint b)
        {
            if (base.IsInfinity)
            {
                return(b);
            }
            if (b.IsInfinity)
            {
                return(this);
            }
            ECCurve        curve      = Curve;
            ECFieldElement rawXCoord  = base.RawXCoord;
            ECFieldElement rawXCoord2 = b.RawXCoord;

            if (rawXCoord.IsZero)
            {
                if (rawXCoord2.IsZero)
                {
                    return(curve.Infinity);
                }
                return(b.Add(this));
            }
            ECFieldElement rawYCoord       = base.RawYCoord;
            ECFieldElement eCFieldElement  = base.RawZCoords[0];
            ECFieldElement rawYCoord2      = b.RawYCoord;
            ECFieldElement eCFieldElement2 = b.RawZCoords[0];
            bool           isOne           = eCFieldElement.IsOne;
            ECFieldElement eCFieldElement3 = rawXCoord2;
            ECFieldElement eCFieldElement4 = rawYCoord2;

            if (!isOne)
            {
                eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
                eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
            }
            bool           isOne2          = eCFieldElement2.IsOne;
            ECFieldElement eCFieldElement5 = rawXCoord;
            ECFieldElement eCFieldElement6 = rawYCoord;

            if (!isOne2)
            {
                eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
                eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
            }
            ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
            ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);

            if (eCFieldElement8.IsZero)
            {
                if (eCFieldElement7.IsZero)
                {
                    return(Twice());
                }
                return(curve.Infinity);
            }
            ECFieldElement eCFieldElement10;
            ECFieldElement y;
            ECFieldElement eCFieldElement12;

            if (rawXCoord2.IsZero)
            {
                ECPoint eCPoint = Normalize();
                rawXCoord = eCPoint.XCoord;
                ECFieldElement yCoord          = eCPoint.YCoord;
                ECFieldElement b2              = rawYCoord2;
                ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
                eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord);
                if (eCFieldElement10.IsZero)
                {
                    return(new SecT409K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed));
                }
                ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
                y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
                eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
            }
            else
            {
                eCFieldElement8 = eCFieldElement8.Square();
                ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
                ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
                eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
                if (eCFieldElement10.IsZero)
                {
                    return(new SecT409K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed));
                }
                ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
                if (!isOne2)
                {
                    eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
                }
                y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
                eCFieldElement12 = eCFieldElement15;
                if (!isOne)
                {
                    eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
                }
            }
            return(new SecT409K1Point(curve, eCFieldElement10, y, new ECFieldElement[1] {
                eCFieldElement12
            }, base.IsCompressed));
        }
예제 #2
0
        public override ECPoint Add(ECPoint b)
        {
            if (this.IsInfinity)
            {
                return(b);
            }
            if (b.IsInfinity)
            {
                return(this);
            }

            ECCurve curve = this.Curve;

            ECFieldElement X1 = this.RawXCoord;
            ECFieldElement X2 = b.RawXCoord;

            if (X1.IsZero)
            {
                if (X2.IsZero)
                {
                    return(curve.Infinity);
                }

                return(b.Add(this));
            }

            ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0];
            ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0];

            bool           Z1IsOne = Z1.IsOne;
            ECFieldElement U2 = X2, S2 = L2;

            if (!Z1IsOne)
            {
                U2 = U2.Multiply(Z1);
                S2 = S2.Multiply(Z1);
            }

            bool           Z2IsOne = Z2.IsOne;
            ECFieldElement U1 = X1, S1 = L1;

            if (!Z2IsOne)
            {
                U1 = U1.Multiply(Z2);
                S1 = S1.Multiply(Z2);
            }

            ECFieldElement A = S1.Add(S2);
            ECFieldElement B = U1.Add(U2);

            if (B.IsZero)
            {
                if (A.IsZero)
                {
                    return(Twice());
                }

                return(curve.Infinity);
            }

            ECFieldElement X3, L3, Z3;

            if (X2.IsZero)
            {
                // TODO This can probably be optimized quite a bit
                ECPoint p = this.Normalize();
                X1 = p.XCoord;
                ECFieldElement Y1 = p.YCoord;

                ECFieldElement Y2 = L2;
                ECFieldElement L  = Y1.Add(Y2).Divide(X1);

                //X3 = L.Square().Add(L).Add(X1).Add(curve.A);
                X3 = L.Square().Add(L).Add(X1).AddOne();
                if (X3.IsZero)
                {
                    return(new SecT163R2Point(curve, X3, curve.B.Sqrt(), IsCompressed));
                }

                ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1);
                L3 = Y3.Divide(X3).Add(X3);
                Z3 = curve.FromBigInteger(BigInteger.One);
            }
            else
            {
                B = B.Square();

                ECFieldElement AU1 = A.Multiply(U1);
                ECFieldElement AU2 = A.Multiply(U2);

                X3 = AU1.Multiply(AU2);
                if (X3.IsZero)
                {
                    return(new SecT163R2Point(curve, X3, curve.B.Sqrt(), IsCompressed));
                }

                ECFieldElement ABZ2 = A.Multiply(B);
                if (!Z2IsOne)
                {
                    ABZ2 = ABZ2.Multiply(Z2);
                }

                L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1));

                Z3 = ABZ2;
                if (!Z1IsOne)
                {
                    Z3 = Z3.Multiply(Z1);
                }
            }

            return(new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed));
        }
예제 #3
0
        public override ECPoint TwicePlus(ECPoint b)
        {
            if (this.IsInfinity)
            {
                return(b);
            }
            if (b.IsInfinity)
            {
                return(Twice());
            }

            ECCurve curve = this.Curve;

            ECFieldElement X1 = this.RawXCoord;

            if (X1.IsZero)
            {
                // A point with X == 0 is it's own Additive inverse
                return(b);
            }

            ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0];

            if (X2.IsZero || !Z2.IsOne)
            {
                return(Twice().Add(b));
            }

            ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0];
            ECFieldElement L2 = b.RawYCoord;

            ECFieldElement X1Sq = X1.Square();
            ECFieldElement L1Sq = L1.Square();
            ECFieldElement Z1Sq = Z1.Square();
            ECFieldElement L1Z1 = L1.Multiply(Z1);

            //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1);
            ECFieldElement T       = Z1Sq.Add(L1Sq).Add(L1Z1);
            ECFieldElement L2plus1 = L2.AddOne();
            //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq);
            ECFieldElement A      = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq);
            ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq);
            ECFieldElement B      = X2Z1Sq.Add(T).Square();

            if (B.IsZero)
            {
                if (A.IsZero)
                {
                    return(b.Twice());
                }

                return(curve.Infinity);
            }

            if (A.IsZero)
            {
                return(new SecT163R2Point(curve, A, curve.B.Sqrt(), IsCompressed));
            }

            ECFieldElement X3 = A.Square().Multiply(X2Z1Sq);
            ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq);
            ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3);

            return(new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed));
        }
예제 #4
0
        protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
        {
            ECFieldElement eCFieldElement  = FromBigInteger(X1);
            ECFieldElement eCFieldElement2 = null;

            if (eCFieldElement.IsZero)
            {
                eCFieldElement2 = B.Sqrt();
            }
            else
            {
                ECFieldElement beta = eCFieldElement.Square().Invert().Multiply(B)
                                      .Add(A)
                                      .Add(eCFieldElement);
                ECFieldElement eCFieldElement3 = SolveQuadraticEquation(beta);
                if (eCFieldElement3 != null)
                {
                    if (eCFieldElement3.TestBitZero() != (yTilde == 1))
                    {
                        eCFieldElement3 = eCFieldElement3.AddOne();
                    }
                    int coordinateSystem = CoordinateSystem;
                    eCFieldElement2 = ((coordinateSystem != 5 && coordinateSystem != 6) ? eCFieldElement3.Multiply(eCFieldElement) : eCFieldElement3.Add(eCFieldElement));
                }
            }
            if (eCFieldElement2 == null)
            {
                throw new ArgumentException("Invalid point compression");
            }
            return(CreateRawPoint(eCFieldElement, eCFieldElement2, withCompression: true));
        }
예제 #5
0
        public override ECPoint Add(ECPoint b)
        {
            ECFieldElement element13;
            ECFieldElement element14;
            ECFieldElement element15;

            if (base.IsInfinity)
            {
                return(b);
            }
            if (b.IsInfinity)
            {
                return(this);
            }
            ECCurve        curve     = this.Curve;
            ECFieldElement rawXCoord = base.RawXCoord;
            ECFieldElement element2  = b.RawXCoord;

            if (rawXCoord.IsZero)
            {
                if (element2.IsZero)
                {
                    return(curve.Infinity);
                }
                return(b.Add(this));
            }
            ECFieldElement rawYCoord = base.RawYCoord;
            ECFieldElement element4  = base.RawZCoords[0];
            ECFieldElement element5  = b.RawYCoord;
            ECFieldElement element6  = b.RawZCoords[0];
            bool           isOne     = element4.IsOne;
            ECFieldElement element7  = element2;
            ECFieldElement element8  = element5;

            if (!isOne)
            {
                element7 = element7.Multiply(element4);
                element8 = element8.Multiply(element4);
            }
            bool           flag2     = element6.IsOne;
            ECFieldElement element9  = rawXCoord;
            ECFieldElement element10 = rawYCoord;

            if (!flag2)
            {
                element9  = element9.Multiply(element6);
                element10 = element10.Multiply(element6);
            }
            ECFieldElement element11 = element10.Add(element8);
            ECFieldElement element12 = element9.Add(element7);

            if (element12.IsZero)
            {
                if (element11.IsZero)
                {
                    return(this.Twice());
                }
                return(curve.Infinity);
            }
            if (element2.IsZero)
            {
                ECPoint point = this.Normalize();
                rawXCoord = point.XCoord;
                ECFieldElement yCoord    = point.YCoord;
                ECFieldElement element17 = element5;
                ECFieldElement element18 = yCoord.Add(element17).Divide(rawXCoord);
                element13 = element18.Square().Add(element18).Add(rawXCoord).Add(curve.A);
                if (element13.IsZero)
                {
                    return(new SecT113R2Point(curve, element13, curve.B.Sqrt(), base.IsCompressed));
                }
                element14 = element18.Multiply(rawXCoord.Add(element13)).Add(element13).Add(yCoord).Divide(element13).Add(element13);
                element15 = curve.FromBigInteger(BigInteger.One);
            }
            else
            {
                element12 = element12.Square();
                ECFieldElement element20 = element11.Multiply(element9);
                ECFieldElement element21 = element11.Multiply(element7);
                element13 = element20.Multiply(element21);
                if (element13.IsZero)
                {
                    return(new SecT113R2Point(curve, element13, curve.B.Sqrt(), base.IsCompressed));
                }
                ECFieldElement x = element11.Multiply(element12);
                if (!flag2)
                {
                    x = x.Multiply(element6);
                }
                element14 = element21.Add(element12).SquarePlusProduct(x, rawYCoord.Add(element4));
                element15 = x;
                if (!isOne)
                {
                    element15 = element15.Multiply(element4);
                }
            }
            return(new SecT113R2Point(curve, element13, element14, new ECFieldElement[] { element15 }, base.IsCompressed));
        }
        public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated)
        {
            ECCurve         c = p.Curve;
            WNafPreCompInfo wnafPreCompInfo = GetWNafPreCompInfo(c.GetPreCompInfo(p, PRECOMP_NAME));

            int iniPreCompLen = 0, reqPreCompLen = 1 << System.Math.Max(0, width - 2);

            ECPoint[] preComp = wnafPreCompInfo.PreComp;
            if (preComp == null)
            {
                preComp = EMPTY_POINTS;
            }
            else
            {
                iniPreCompLen = preComp.Length;
            }

            if (iniPreCompLen < reqPreCompLen)
            {
                preComp = ResizeTable(preComp, reqPreCompLen);

                if (reqPreCompLen == 1)
                {
                    preComp[0] = p.Normalize();
                }
                else
                {
                    int curPreCompLen = iniPreCompLen;
                    if (curPreCompLen == 0)
                    {
                        preComp[0]    = p;
                        curPreCompLen = 1;
                    }

                    ECFieldElement iso = null;

                    if (reqPreCompLen == 2)
                    {
                        preComp[1] = p.ThreeTimes();
                    }
                    else
                    {
                        ECPoint twiceP = wnafPreCompInfo.Twice, last = preComp[curPreCompLen - 1];
                        if (twiceP == null)
                        {
                            twiceP = preComp[0].Twice();
                            wnafPreCompInfo.Twice = twiceP;

                            /*
                             * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism
                             * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This
                             * also requires scaling the initial point's X, Y coordinates, and reversing the
                             * isomorphism as part of the subsequent normalization.
                             *
                             *  NOTE: The correctness of this optimization depends on:
                             *      1) additions do not use the curve's A, B coefficients.
                             *      2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ...
                             */
                            if (ECAlgorithms.IsFpCurve(c) && c.FieldSize >= 64)
                            {
                                switch (c.CoordinateSystem)
                                {
                                case ECCurve.COORD_JACOBIAN:
                                case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
                                case ECCurve.COORD_JACOBIAN_MODIFIED:
                                {
                                    iso    = twiceP.GetZCoord(0);
                                    twiceP = c.CreatePoint(twiceP.XCoord.ToBigInteger(),
                                                           twiceP.YCoord.ToBigInteger());

                                    ECFieldElement iso2 = iso.Square(), iso3 = iso2.Multiply(iso);
                                    last = last.ScaleX(iso2).ScaleY(iso3);

                                    if (iniPreCompLen == 0)
                                    {
                                        preComp[0] = last;
                                    }
                                    break;
                                }
                                }
                            }
                        }

                        while (curPreCompLen < reqPreCompLen)
                        {
                            /*
                             * Compute the new ECPoints for the precomputation array. The values 1, 3,
                             * 5, ..., 2^(width-1)-1 times p are computed
                             */
                            preComp[curPreCompLen++] = last = last.Add(twiceP);
                        }
                    }

                    /*
                     * Having oft-used operands in affine form makes operations faster.
                     */
                    c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso);
                }
            }

            wnafPreCompInfo.PreComp = preComp;

            if (includeNegated)
            {
                ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg;

                int pos;
                if (preCompNeg == null)
                {
                    pos        = 0;
                    preCompNeg = new ECPoint[reqPreCompLen];
                }
                else
                {
                    pos = preCompNeg.Length;
                    if (pos < reqPreCompLen)
                    {
                        preCompNeg = ResizeTable(preCompNeg, reqPreCompLen);
                    }
                }

                while (pos < reqPreCompLen)
                {
                    preCompNeg[pos] = preComp[pos].Negate();
                    ++pos;
                }

                wnafPreCompInfo.PreCompNeg = preCompNeg;
            }

            c.SetPreCompInfo(p, PRECOMP_NAME, wnafPreCompInfo);

            return(wnafPreCompInfo);
        }