Exemplo n.º 1
0
        protected static ECFieldElement[] GetInitialZCoords(ECCurve curve)
        {
            // Cope with null curve, most commonly used by implicitlyCa
            int coord = null == curve ? ECCurve.COORD_AFFINE : curve.CoordinateSystem;

            switch (coord)
            {
                case ECCurve.COORD_AFFINE:
                case ECCurve.COORD_LAMBDA_AFFINE:
                    return EMPTY_ZS;
                default:
                    break;
            }

            ECFieldElement one = curve.FromBigInteger(BigInteger.One);

            switch (coord)
            {
                case ECCurve.COORD_HOMOGENEOUS:
                case ECCurve.COORD_JACOBIAN:
                case ECCurve.COORD_LAMBDA_PROJECTIVE:
                    return new ECFieldElement[] { one };
                case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
                    return new ECFieldElement[] { one, one, one };
                case ECCurve.COORD_JACOBIAN_MODIFIED:
                    return new ECFieldElement[] { one, curve.A };
                default:
                    throw new ArgumentException("unknown coordinate system");
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Hashes a seed t into a point T on the curve. Returns null if t is unsuitable.
        /// </summary>
        /// <param name="curve">The elliptic curve in Weierstrass form</param>
        /// <param name="t">The seed</param>
        /// <returns>A random point T uniquely determined by seed t, otherwise null</returns>
        public static ECPoint?HashToWeierstrassCurve(ECCurve curve, byte[] t)
        {
            ECFieldElement x, ax, x3, y, y2;

            BigInteger P      = curve.Field.Characteristic;
            SHA256?    sha256 = SHA256.Create();
            BigInteger hash   = new BigInteger(sha256.ComputeHash(t));

            // Check that the hash is within valid range
            if (hash.CompareTo(BigInteger.One) < 0 || hash.CompareTo(P) >= 0)
            {
                return(null);
            }

            // A valid point (x,y) must satisfy: y^2 = x^3 + Ax + B mod P
            // Convert hash from BigInt to FieldElement x modulo P
            x  = curve.FromBigInteger(hash);        // x
            ax = x.Multiply(curve.A);               // Ax
            x3 = x.Square().Multiply(x);            // x^3 = x^2 * x
            y2 = x3.Add(ax).Add(curve.B);           // y^2 = x^3 + Ax + B
            y  = y2.Sqrt();                         // y = sqrt(x^3 + Ax + B)

            // y == null if square root mod P does not exist
            if (y == null)
            {
                return(null);
            }

            ECPoint T = curve.CreatePoint(x.ToBigInteger(), y.ToBigInteger());

            // Use the built-in point validator, which also checks for membership
            // in weak subgroups
            if (!T.IsValid())
            {
                return(null);
            }

            return(T);
        }
Exemplo n.º 3
0
        private void ImplSqrtTest(ECCurve c)
        {
            if (ECAlgorithms.IsFpCurve(c))
            {
                BigInteger p = c.Field.Characteristic;
                BigInteger pMinusOne = p.Subtract(BigInteger.One);
                BigInteger legendreExponent = p.ShiftRight(1);

                int count = 0;
                while (count < 10)
                {
                    BigInteger nonSquare = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusOne, secRand);
                    if (!nonSquare.ModPow(legendreExponent, p).Equals(BigInteger.One))
                    {
                        ECFieldElement root = c.FromBigInteger(nonSquare).Sqrt();
                        Assert.IsNull(root);
                        ++count;
                    }
                }
            }
        }
Exemplo n.º 4
0
        private void ImplSqrtTest(ECCurve c)
        {
            if (ECAlgorithms.IsFpCurve(c))
            {
                BigInteger p = c.Field.Characteristic;
                BigInteger pMinusOne = p.Subtract(BigInteger.One);
                BigInteger legendreExponent = p.ShiftRight(1);

                int count = 0;
                while (count < 10)
                {
                    BigInteger nonSquare = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusOne, secRand);
                    if (!nonSquare.ModPow(legendreExponent, p).Equals(BigInteger.One))
                    {
                        ECFieldElement root = c.FromBigInteger(nonSquare).Sqrt();
                        Assert.IsNull(root);
                        ++count;
                    }
                }
            }
            else if (ECAlgorithms.IsF2mCurve(c))
            {
                int m = c.FieldSize;
                BigInteger x = new BigInteger(m, secRand);
                ECFieldElement fe = c.FromBigInteger(x);
                for (int i = 0; i < 100; ++i)
                {
                    ECFieldElement sq = fe.Square();
                    ECFieldElement check = sq.Sqrt();
                    Assert.AreEqual(fe, check);
                    fe = sq;
                }
            }
        }
Exemplo n.º 5
0
        public override ECPoint Add(ECPoint b)
        {
            if (base.IsInfinity)
            {
                return(b);
            }
            if (b.IsInfinity)
            {
                return(this);
            }
            ECCurve        curve            = this.Curve;
            int            coordinateSystem = curve.CoordinateSystem;
            ECFieldElement rawXCoord        = base.RawXCoord;
            ECFieldElement rawXCoord2       = b.RawXCoord;
            int            num = coordinateSystem;

            switch (num)
            {
            case 0:
            {
                ECFieldElement rawYCoord       = base.RawYCoord;
                ECFieldElement rawYCoord2      = b.RawYCoord;
                ECFieldElement eCFieldElement  = rawXCoord.Add(rawXCoord2);
                ECFieldElement eCFieldElement2 = rawYCoord.Add(rawYCoord2);
                if (!eCFieldElement.IsZero)
                {
                    ECFieldElement eCFieldElement3 = eCFieldElement2.Divide(eCFieldElement);
                    ECFieldElement eCFieldElement4 = eCFieldElement3.Square().Add(eCFieldElement3).Add(eCFieldElement).Add(curve.A);
                    ECFieldElement y = eCFieldElement3.Multiply(rawXCoord.Add(eCFieldElement4)).Add(eCFieldElement4).Add(rawYCoord);
                    return(new F2mPoint(curve, eCFieldElement4, y, base.IsCompressed));
                }
                if (eCFieldElement2.IsZero)
                {
                    return(this.Twice());
                }
                return(curve.Infinity);
            }

            case 1:
            {
                ECFieldElement rawYCoord3      = base.RawYCoord;
                ECFieldElement eCFieldElement5 = base.RawZCoords[0];
                ECFieldElement rawYCoord4      = b.RawYCoord;
                ECFieldElement eCFieldElement6 = b.RawZCoords[0];
                bool           isOne           = eCFieldElement5.IsOne;
                ECFieldElement eCFieldElement7 = rawYCoord4;
                ECFieldElement eCFieldElement8 = rawXCoord2;
                if (!isOne)
                {
                    eCFieldElement7 = eCFieldElement7.Multiply(eCFieldElement5);
                    eCFieldElement8 = eCFieldElement8.Multiply(eCFieldElement5);
                }
                bool           isOne2           = eCFieldElement6.IsOne;
                ECFieldElement eCFieldElement9  = rawYCoord3;
                ECFieldElement eCFieldElement10 = rawXCoord;
                if (!isOne2)
                {
                    eCFieldElement9  = eCFieldElement9.Multiply(eCFieldElement6);
                    eCFieldElement10 = eCFieldElement10.Multiply(eCFieldElement6);
                }
                ECFieldElement eCFieldElement11 = eCFieldElement7.Add(eCFieldElement9);
                ECFieldElement eCFieldElement12 = eCFieldElement8.Add(eCFieldElement10);
                if (!eCFieldElement12.IsZero)
                {
                    ECFieldElement eCFieldElement13 = eCFieldElement12.Square();
                    ECFieldElement eCFieldElement14 = eCFieldElement13.Multiply(eCFieldElement12);
                    ECFieldElement b2 = isOne ? eCFieldElement6 : (isOne2 ? eCFieldElement5 : eCFieldElement5.Multiply(eCFieldElement6));
                    ECFieldElement eCFieldElement15 = eCFieldElement11.Add(eCFieldElement12);
                    ECFieldElement eCFieldElement16 = eCFieldElement15.MultiplyPlusProduct(eCFieldElement11, eCFieldElement13, curve.A).Multiply(b2).Add(eCFieldElement14);
                    ECFieldElement x  = eCFieldElement12.Multiply(eCFieldElement16);
                    ECFieldElement b3 = isOne2 ? eCFieldElement13 : eCFieldElement13.Multiply(eCFieldElement6);
                    ECFieldElement y2 = eCFieldElement11.MultiplyPlusProduct(rawXCoord, eCFieldElement12, rawYCoord3).MultiplyPlusProduct(b3, eCFieldElement15, eCFieldElement16);
                    ECFieldElement eCFieldElement17 = eCFieldElement14.Multiply(b2);
                    return(new F2mPoint(curve, x, y2, new ECFieldElement[]
                        {
                            eCFieldElement17
                        }, base.IsCompressed));
                }
                if (eCFieldElement11.IsZero)
                {
                    return(this.Twice());
                }
                return(curve.Infinity);
            }

            default:
                if (num != 6)
                {
                    throw new InvalidOperationException("unsupported coordinate system");
                }
                if (rawXCoord.IsZero)
                {
                    if (rawXCoord2.IsZero)
                    {
                        return(curve.Infinity);
                    }
                    return(b.Add(this));
                }
                else
                {
                    ECFieldElement rawYCoord5       = base.RawYCoord;
                    ECFieldElement eCFieldElement18 = base.RawZCoords[0];
                    ECFieldElement rawYCoord6       = b.RawYCoord;
                    ECFieldElement eCFieldElement19 = b.RawZCoords[0];
                    bool           isOne3           = eCFieldElement18.IsOne;
                    ECFieldElement eCFieldElement20 = rawXCoord2;
                    ECFieldElement eCFieldElement21 = rawYCoord6;
                    if (!isOne3)
                    {
                        eCFieldElement20 = eCFieldElement20.Multiply(eCFieldElement18);
                        eCFieldElement21 = eCFieldElement21.Multiply(eCFieldElement18);
                    }
                    bool           isOne4           = eCFieldElement19.IsOne;
                    ECFieldElement eCFieldElement22 = rawXCoord;
                    ECFieldElement eCFieldElement23 = rawYCoord5;
                    if (!isOne4)
                    {
                        eCFieldElement22 = eCFieldElement22.Multiply(eCFieldElement19);
                        eCFieldElement23 = eCFieldElement23.Multiply(eCFieldElement19);
                    }
                    ECFieldElement eCFieldElement24 = eCFieldElement23.Add(eCFieldElement21);
                    ECFieldElement eCFieldElement25 = eCFieldElement22.Add(eCFieldElement20);
                    if (!eCFieldElement25.IsZero)
                    {
                        ECFieldElement eCFieldElement27;
                        ECFieldElement y3;
                        ECFieldElement eCFieldElement29;
                        if (rawXCoord2.IsZero)
                        {
                            ECPoint eCPoint = this.Normalize();
                            rawXCoord = eCPoint.RawXCoord;
                            ECFieldElement yCoord           = eCPoint.YCoord;
                            ECFieldElement b4               = rawYCoord6;
                            ECFieldElement eCFieldElement26 = yCoord.Add(b4).Divide(rawXCoord);
                            eCFieldElement27 = eCFieldElement26.Square().Add(eCFieldElement26).Add(rawXCoord).Add(curve.A);
                            if (eCFieldElement27.IsZero)
                            {
                                return(new F2mPoint(curve, eCFieldElement27, curve.B.Sqrt(), base.IsCompressed));
                            }
                            ECFieldElement eCFieldElement28 = eCFieldElement26.Multiply(rawXCoord.Add(eCFieldElement27)).Add(eCFieldElement27).Add(yCoord);
                            y3 = eCFieldElement28.Divide(eCFieldElement27).Add(eCFieldElement27);
                            eCFieldElement29 = curve.FromBigInteger(BigInteger.One);
                        }
                        else
                        {
                            eCFieldElement25 = eCFieldElement25.Square();
                            ECFieldElement eCFieldElement30 = eCFieldElement24.Multiply(eCFieldElement22);
                            ECFieldElement eCFieldElement31 = eCFieldElement24.Multiply(eCFieldElement20);
                            eCFieldElement27 = eCFieldElement30.Multiply(eCFieldElement31);
                            if (eCFieldElement27.IsZero)
                            {
                                return(new F2mPoint(curve, eCFieldElement27, curve.B.Sqrt(), base.IsCompressed));
                            }
                            ECFieldElement eCFieldElement32 = eCFieldElement24.Multiply(eCFieldElement25);
                            if (!isOne4)
                            {
                                eCFieldElement32 = eCFieldElement32.Multiply(eCFieldElement19);
                            }
                            y3 = eCFieldElement31.Add(eCFieldElement25).SquarePlusProduct(eCFieldElement32, rawYCoord5.Add(eCFieldElement18));
                            eCFieldElement29 = eCFieldElement32;
                            if (!isOne3)
                            {
                                eCFieldElement29 = eCFieldElement29.Multiply(eCFieldElement18);
                            }
                        }
                        return(new F2mPoint(curve, eCFieldElement27, y3, new ECFieldElement[]
                        {
                            eCFieldElement29
                        }, base.IsCompressed));
                    }
                    if (eCFieldElement24.IsZero)
                    {
                        return(this.Twice());
                    }
                    return(curve.Infinity);
                }
                break;
            }
        }