예제 #1
0
        public ECDomainParameters(
            ECCurve curve,
            ECPoint g,
            BigInteger n,
            BigInteger h,
            byte[]      seed)
        {
            if (curve == null)
            {
                throw new ArgumentNullException("curve");
            }
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (n == null)
            {
                throw new ArgumentNullException("n");
            }
            if (h == null)
            {
                throw new ArgumentNullException("h");
            }

            this._curve = curve;
            this._g     = g.Normalize();
            this._n     = n;
            this._h     = h;
            this._seed  = seed.DeepCopy();
        }
예제 #2
0
        /// <summary>
        /// 验签
        /// </summary>
        /// <param name="md">sm3摘要</param>
        /// <param name="userKey">根据公钥decode一个ecpoint对象</param>
        /// <param name="r">没有特殊含义</param>
        /// <param name="s">没有特殊含义</param>
        /// <param name="sm2Result">sm2Result 接收参数的对象</param>
        public void sm2Verify(byte[] md, ECPoint userKey, BigInteger r, BigInteger s, SM2Result sm2Result)
        {
            sm2Result.R = null;
            BigInteger e = new BigInteger(1, md);
            BigInteger t = r.Add(s).Mod(this.ecc_n);

            if (t.Equals(BigInteger.Zero))
            {
                return;
            }
            else
            {
                ECPoint x1y1 = ecc_point_g.Multiply(sm2Result.s);
                //System.out.println("计算曲线点X0: "+ x1y1.normalize().getXCoord().toBigInteger().toString(16));
                //System.out.println("计算曲线点Y0: "+ x1y1.normalize().getYCoord().toBigInteger().toString(16));
                //System.out.println("");

                x1y1 = x1y1.Add(userKey.Multiply(t));
                //System.out.println("计算曲线点X1: "+ x1y1.normalize().getXCoord().toBigInteger().toString(16));
                //System.out.println("计算曲线点Y1: "+ x1y1.normalize().getYCoord().toBigInteger().toString(16));
                //System.out.println("");
                sm2Result.R = e.Add(x1y1.Normalize().XCoord.ToBigInteger()).Mod(this.ecc_n);
                //System.out.println("R: " + sm2Result.R.toString(16));
                return;
            }
        }
예제 #3
0
        public ECDomainParameters(
            ECCurve curve,
            ECPoint g,
            BigInteger n,
            BigInteger h,
            byte[]      seed)
        {
            if (curve == null)
            {
                throw new ArgumentNullException("curve");
            }
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (n == null)
            {
                throw new ArgumentNullException("n");
            }
            if (h == null)
            {
                throw new ArgumentNullException("h");
            }

            this.curve = curve;
            this.g     = g.Normalize();
            this.n     = n;
            this.h     = h;
            this.seed  = Arrays.Clone(seed);
        }
        public static byte[] encodePoint(ECPoint Q)
        {
            /*if (!Q.isCompressed())
             *    Q=new ECPoint.F2m(Q.getCurve(),Q.getX(),Q.getY(),true);
             *
             * byte[] bytes=Q.getEncoded();
             *
             * if (bytes[0]==0x02)
             *    bytes[bytes.length-1]&=0xFE;
             * else if (bytes[0]==0x02)
             *    bytes[bytes.length-1]|=0x01;
             *
             * return Arrays.copyOfRange(bytes, 1, bytes.length);*/

            Q = Q.Normalize();

            ECFieldElement x = Q.AffineXCoord;

            byte[] bytes = x.GetEncoded();

            if (!x.IsZero)
            {
                ECFieldElement z = Q.AffineYCoord.Divide(x);
                if (trace(z).IsOne)
                {
                    bytes[bytes.Length - 1] |= 0x01;
                }
                else
                {
                    bytes[bytes.Length - 1] &= 0xFE;
                }
            }

            return(bytes);
        }
예제 #5
0
 public ECPublicKeyParameters(string algorithm, ECPoint q, ECDomainParameters parameters) : base(algorithm, false, parameters)
 {
     if (q == null)
     {
         throw new ArgumentNullException("q");
     }
     this.q = q.Normalize();
 }
예제 #6
0
 public ECPublicKeyParameters(string algorithm, ECPoint q, DerObjectIdentifier publicKeyParamSet) : base(algorithm, false, publicKeyParamSet)
 {
     if (q == null)
     {
         throw new ArgumentNullException("q");
     }
     this.q = q.Normalize();
 }
예제 #7
0
 public ECPublicKeyParameters(ECPoint q, DerObjectIdentifier publicKeyParamSet) : base("ECGOST3410", false, publicKeyParamSet)
 {
     if (q == null)
     {
         throw new ArgumentNullException("q");
     }
     this.q = q.Normalize();
 }
예제 #8
0
 public static bool IsSameAs(this OwnECPoint point1, ECPoint point2)
 {
     if (point1.IsInfinity || point2.IsInfinity)
     {
         return(point1.IsInfinity && point2.IsInfinity);
     }
     point2 = point2.Normalize();
     return(point1.X.ToBigInteger() == point2.X && point1.Y.ToBigInteger() == point2.Y);
 }
예제 #9
0
		private ECPrivateKeyParameters ParseKey(string data)
		{
			Dictionary<string, string> values = ToDictionnary(data);

			var curveName = values["curve"].Replace("NIST", "");
			var curve = SecNamedCurves.GetByOid(curves[curveName]);
			var domain = new ECDomainParameters(curve.Curve, curve.G, new BigInteger(values["q"], 16), curve.H);
			Assert.Equal(domain.N, curve.N);

			var key = new ECPrivateKeyParameters(new BigInteger(values["x"], 16), domain);

			ECPoint pub = curve.G.Multiply(key.D);

			Assert.Equal(pub.Normalize().XCoord.ToBigInteger(), new BigInteger(values["Ux"], 16));
			Assert.Equal(pub.Normalize().YCoord.ToBigInteger(), new BigInteger(values["Uy"], 16));

			return key;
		}
예제 #10
0
        public PubKey GetPubKey(bool isCompressed)
        {
            ECPoint q = GetPublicKeyParameters().Q;

            //Pub key (q) is composed into X and Y, the compressed form only include X, which can derive Y along with 02 or 03 prepent depending on whether Y in even or odd.
            q = q.Normalize();
            byte[] result = Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()).GetEncoded(isCompressed);
            return(new PubKey(result));
        }
 public ECPublicKeyParameters(string algorithm, ECPoint q, DerObjectIdentifier publicKeyParamSet)
     : base(algorithm, isPrivate: false, publicKeyParamSet)
 {
     //IL_0011: Unknown result type (might be due to invalid IL or missing references)
     if (q == null)
     {
         throw new ArgumentNullException("q");
     }
     this.q = q.Normalize();
 }
예제 #12
0
        private void Reset()
        {
            sm3keybase = new SM3Digest();
            sm3c3      = new SM3Digest();


            byte[] p;

            p = p2.Normalize().XCoord.ToBigInteger().ToByteArray();
            sm3keybase.BlockUpdate(p, 0, p.Length);
            sm3c3.BlockUpdate(p, 0, p.Length);


            p = p2.Normalize().YCoord.ToBigInteger().ToByteArray();
            sm3keybase.BlockUpdate(p, 0, p.Length);


            ct = 1;
            NextKey();
        }
예제 #13
0
 /// <summary>
 /// Constructor with explicit co-factor and generation seed.
 /// </summary>
 /// <param name="curve">The curve for these domain parameters.</param>
 /// <param name="G">The base point G for the domain parameters.</param>
 /// <param name="n">The order for the domain parameters.</param>
 /// <param name="h">The co-factor.</param>
 /// <param name="seed">The seed value used to generate the domain parameters.</param>
 public ECDomainParameters(
     ECCurve curve,
     ECPoint G,
     BigInteger n,
     BigInteger h,
     byte[] seed)
 {
     this.curve = curve;
     this.g     = G.Normalize();
     this.n     = n;
     this.h     = h;
     this.seed  = Arrays.Clone(seed);
 }
예제 #14
0
 public virtual ECPoint ImportPoint(ECPoint p)
 {
     if (this == p.Curve)
     {
         return(p);
     }
     if (p.IsInfinity)
     {
         return(Infinity);
     }
     p = p.Normalize();
     return(ValidatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed));
 }
예제 #15
0
        public static string GenerateSecp256k1PublicKey(string privateKey, bool useCompression)
        {
            var        Ecc          = SecNamedCurves.GetByName("secp256k1");
            var        DomainParams = new ECDomainParameters(Ecc.Curve, Ecc.G, Ecc.N, Ecc.H);
            var        bytes        = Hex.Hex2Bytes(privateKey);
            BigInteger d            = new BigInteger(bytes);
            ECPoint    q            = DomainParams.G.Multiply(d);

            q = q.Normalize();
            var     publicParams = new ECPublicKeyParameters(q, DomainParams);
            FpPoint fp           = new FpPoint(Ecc.Curve, q.AffineXCoord, q.AffineYCoord);

            return(Hex.Bytes2Hex(fp.GetEncoded(useCompression)));
        }
예제 #16
0
        /// <summary>
        /// 获取Z值
        /// Z=SM3(ENTL∣∣userId∣∣a∣∣b∣∣gx∣∣gy ∣∣x∣∣y)
        /// </summary>
        /// <param name="userId">签名方的用户身份标识</param>
        /// <param name="userKey">签名方公钥</param>
        /// <returns></returns>
        public virtual byte[] Sm2GetZ(byte[] userId, ECPoint userKey)
        {
            SM3Digest sm3 = new SM3Digest();

            byte[] p;
            // ENTL由2个字节标识的ID的比特长度
            int len = userId.Length * 8;

            sm3.Update((byte)(len >> 8 & 0x00ff));
            sm3.Update((byte)(len & 0x00ff));

            // userId用户身份标识ID
            sm3.BlockUpdate(userId, 0, userId.Length);

            // a,b为系统曲线参数;
            p = EccA.ToByteArray();
            sm3.BlockUpdate(p, 0, p.Length);
            p = EccB.ToByteArray();
            sm3.BlockUpdate(p, 0, p.Length);
            //  gx、gy为基点
            p = EccGx.ToByteArray();
            sm3.BlockUpdate(p, 0, p.Length);
            p = EccGy.ToByteArray();
            sm3.BlockUpdate(p, 0, p.Length);

            // x,y用户的公钥的X和Y
            p = userKey.Normalize().XCoord.ToBigInteger().ToByteArray();
            sm3.BlockUpdate(p, 0, p.Length);
            p = userKey.Normalize().YCoord.ToBigInteger().ToByteArray();
            sm3.BlockUpdate(p, 0, p.Length);

            // Z
            byte[] md = new byte[sm3.GetDigestSize()];
            sm3.DoFinal(md, 0);

            return(md);
        }
예제 #17
0
    protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
    {
        ECPoint eCPoint      = p.Normalize();
        ECPoint eCPoint2     = eCPoint.Negate();
        ECPoint eCPoint3     = eCPoint;
        int     bitLength    = k.BitLength;
        int     lowestSetBit = k.GetLowestSetBit();
        int     num          = bitLength;

        while (--num > lowestSetBit)
        {
            eCPoint3 = eCPoint3.TwicePlus(k.TestBit(num) ? eCPoint : eCPoint2);
        }
        return(eCPoint3.TimesPow2(lowestSetBit));
    }
예제 #18
0
        public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
        {
            BigInteger n = key.Parameters.N;

            if (r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }
            BigInteger bigInteger = CalculateE(n, message);
            BigInteger val        = s.ModInverse(n);
            BigInteger a          = bigInteger.Multiply(val).Mod(n);
            BigInteger b          = r.Multiply(val).Mod(n);
            ECPoint    g          = key.Parameters.G;
            ECPoint    q          = ((ECPublicKeyParameters)key).Q;
            ECPoint    eCPoint    = ECAlgorithms.SumOfTwoMultiplies(g, a, q, b);

            if (eCPoint.IsInfinity)
            {
                return(false);
            }
            ECCurve curve = eCPoint.Curve;

            if (curve != null)
            {
                BigInteger cofactor = curve.Cofactor;
                if (cofactor != null && cofactor.CompareTo(Eight) <= 0)
                {
                    ECFieldElement denominator = GetDenominator(curve.CoordinateSystem, eCPoint);
                    if (denominator != null && !denominator.IsZero)
                    {
                        ECFieldElement xCoord = eCPoint.XCoord;
                        while (curve.IsValidFieldElement(r))
                        {
                            ECFieldElement eCFieldElement = curve.FromBigInteger(r).Multiply(denominator);
                            if (eCFieldElement.Equals(xCoord))
                            {
                                return(true);
                            }
                            r = r.Add(n);
                        }
                        return(false);
                    }
                }
            }
            BigInteger bigInteger2 = eCPoint.Normalize().AffineXCoord.ToBigInteger().Mod(n);

            return(bigInteger2.Equals(r));
        }
예제 #19
0
        public virtual ECPoint ImportPoint(ECPoint p)
        {
            if (this == p.Curve)
            {
                return(p);
            }
            if (p.IsInfinity)
            {
                return(Infinity);
            }

            // TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates.
            p = p.Normalize();

            return(CreatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed));
        }
예제 #20
0
        public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
        {
            BigInteger n = this.key.Parameters.N;

            if (((r.SignValue < 1) || (s.SignValue < 1)) || ((r.CompareTo(n) >= 0) || (s.CompareTo(n) >= 0)))
            {
                return(false);
            }
            BigInteger integer2 = this.CalculateE(n, message);
            BigInteger val      = s.ModInverse(n);
            BigInteger a        = integer2.Multiply(val).Mod(n);
            BigInteger b        = r.Multiply(val).Mod(n);
            ECPoint    g        = this.key.Parameters.G;
            ECPoint    q        = ((ECPublicKeyParameters)this.key).Q;
            ECPoint    p        = ECAlgorithms.SumOfTwoMultiplies(g, a, q, b);

            if (p.IsInfinity)
            {
                return(false);
            }
            ECCurve curve = p.Curve;

            if (curve != null)
            {
                BigInteger cofactor = curve.Cofactor;
                if ((cofactor != null) && (cofactor.CompareTo(Eight) <= 0))
                {
                    ECFieldElement denominator = this.GetDenominator(curve.CoordinateSystem, p);
                    if ((denominator != null) && !denominator.IsZero)
                    {
                        ECFieldElement xCoord = p.XCoord;
                        while (curve.IsValidFieldElement(r))
                        {
                            if (curve.FromBigInteger(r).Multiply(denominator).Equals(xCoord))
                            {
                                return(true);
                            }
                            r = r.Add(n);
                        }
                        return(false);
                    }
                }
            }
            return(p.Normalize().AffineXCoord.ToBigInteger().Mod(n).Equals(r));
        }
예제 #21
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int[]   array    = WNafUtilities.GenerateCompactNaf(k);
            ECPoint eCPoint  = p.Normalize();
            ECPoint eCPoint2 = eCPoint.Negate();
            ECPoint eCPoint3 = p.Curve.Infinity;
            int     num      = array.Length;

            while (--num >= 0)
            {
                int num2 = array[num];
                int num3 = num2 >> 16;
                int e    = num2 & 65535;
                eCPoint3 = eCPoint3.TwicePlus((num3 < 0) ? eCPoint2 : eCPoint);
                eCPoint3 = eCPoint3.TimesPow2(e);
            }
            return(eCPoint3);
        }
        /**
         * 'Zeroless' Signed Digit Left-to-Right.
         */
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            ECPoint addP = p.Normalize(), subP = addP.Negate();

            ECPoint R0 = addP;

            int n = k.BitLength;
            int s = k.GetLowestSetBit();

            int i = n;
            while (--i > s)
            {
                R0 = R0.TwicePlus(k.TestBit(i) ? addP : subP);
            }

            R0 = R0.TimesPow2(s);

            return R0;
        }
        /**
         * 'Zeroless' Signed Digit Left-to-Right.
         */
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            ECPoint addP = p.Normalize(), subP = addP.Negate();

            ECPoint R0 = addP;

            int n = k.BitLength;
            int s = k.GetLowestSetBit();

            int i = n;

            while (--i > s)
            {
                R0 = R0.TwicePlus(k.TestBit(i) ? addP : subP);
            }

            R0 = R0.TimesPow2(s);

            return(R0);
        }
예제 #24
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int[] naf = WNafUtilities.GenerateCompactNaf(k);

            ECPoint addP = p.Normalize(), subP = addP.Negate();

            ECPoint R = p.Curve.Infinity;

            int i = naf.Length;
            while (--i >= 0)
            {
                int ni = naf[i];
                int digit = ni >> 16, zeroes = ni & 0xFFFF;

                R = R.TwicePlus(digit < 0 ? subP : addP);
                R = R.TimesPow2(zeroes);
            }

            return R;
        }
예제 #25
0
        private static ECPoint Validate(ECPoint q)
        {
            if (q == null)
            {
                throw new ArgumentNullException("q");
            }
            if (q.IsInfinity)
            {
                throw new ArgumentException("point at infinity", "q");
            }

            q = q.Normalize();

            if (!q.IsValid())
            {
                throw new ArgumentException("point not on curve", "q");
            }

            return(q);
        }
예제 #26
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int[] naf = WNafUtilities.GenerateCompactNaf(k);

            ECPoint addP = p.Normalize(), subP = addP.Negate();

            ECPoint R = p.Curve.Infinity;

            int i = naf.Length;

            while (--i >= 0)
            {
                int ni = naf[i];
                int digit = ni >> 16, zeroes = ni & 0xFFFF;

                R = R.TwicePlus(digit < 0 ? subP : addP);
                R = R.TimesPow2(zeroes);
            }

            return(R);
        }
예제 #27
0
        public PubKey Derivate(byte[] cc, uint nChild, out byte[] ccChild)
        {
            byte[] lr = null;
            var    l  = new byte[32];
            var    r  = new byte[32];

            if ((nChild >> 31) == 0)
            {
                byte[] pubKey = ToBytes();
                lr = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray());
            }
            else
            {
                throw new InvalidOperationException("A public key can't derivate an hardened child");
            }
            Array.Copy(lr, l, 32);
            Array.Copy(lr, 32, r, 0, 32);
            ccChild = r;


            BigInteger N          = ECKey.CURVE.N;
            var        parse256LL = new BigInteger(1, l);

            if (parse256LL.CompareTo(N) >= 0)
            {
                throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again.");
            }

            ECPoint q = ECKey.CURVE.G.Multiply(parse256LL).Add(this.ECKey.GetPublicKeyParameters().Q);

            if (q.IsInfinity)
            {
                throw new InvalidOperationException("You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again.");
            }

            q = q.Normalize();
            var p = new FpPoint(ECKey.CURVE.Curve, q.XCoord, q.YCoord, true);

            return(new PubKey(p.GetEncoded()));
        }
예제 #28
0
        public X9ECParameters(
            ECCurve curve,
            ECPoint g,
            BigInteger n,
            BigInteger h,
            byte[]              seed)
        {
            this.curve = curve;
            this.g     = g.Normalize();
            this.n     = n;
            this.h     = h;
            this.seed  = seed;

            if (ECAlgorithms.IsFpCurve(curve))
            {
                this.fieldID = new X9FieldID(curve.Field.Characteristic);
            }
            else if (ECAlgorithms.IsF2mCurve(curve))
            {
                IPolynomialExtensionField field = (IPolynomialExtensionField)curve.Field;
                int[] exponents = field.MinimalPolynomial.GetExponentsPresent();
                if (exponents.Length == 3)
                {
                    this.fieldID = new X9FieldID(exponents[2], exponents[1]);
                }
                else if (exponents.Length == 5)
                {
                    this.fieldID = new X9FieldID(exponents[4], exponents[1], exponents[2], exponents[3]);
                }
                else
                {
                    throw new ArgumentException("Only trinomial and pentomial curves are supported");
                }
            }
            else
            {
                throw new ArgumentException("'curve' is of an unsupported type");
            }
        }
예제 #29
0
        /// <summary>
        /// Exchange shared secret through ECDH
        /// </summary>
        /// <param name="key">Private key</param>
        /// <returns>Shared pubkey</returns>
        public PubKey GetSharedPubkey(Key key)
        {
            ECPublicKeyParameters  pub     = this._ECKey.GetPublicKeyParameters();
            ECPrivateKeyParameters privKey = key._ECKey.PrivateKey;

            if (!pub.Parameters.Equals(privKey.Parameters))
            {
                throw new InvalidOperationException("ECDH public key has wrong domain parameters");
            }

            ECPoint q = pub.Q.Multiply(privKey.D).Normalize();

            if (q.IsInfinity)
            {
                throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH");
            }

            ECPoint pubkey = ECKey.Secp256k1.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger());

            pubkey = pubkey.Normalize();

            return(new ECKey(pubkey.GetEncoded(true), false).GetPubKey(true));
        }
예제 #30
0
        internal static ECPoint Validated(ECPoint q)
        {
            // FSM_STATE:5.8, "FIPS 186-3/SP 800-89 ASSURANCES", "The module is performing FIPS 186-3/SP 800-89 Assurances self-test"
            // FSM_TRANS:5.9, "CONDITIONAL TEST", "FIPS 186-3/SP 800-89 ASSURANCES CHECK", "Invoke FIPS 186-3/SP 800-89 Assurances test"
            if (q == null)
            {
                throw new ArgumentException("Point has null value");
            }

            if (q.IsInfinity)
            {
                throw new ArgumentException("Point at infinity");
            }

            q = q.Normalize();

            if (!q.IsValid())
            {
                throw new ArgumentException("Point not on curve");
            }

            // FSM_TRANS:5.10, "FIPS 186-3/SP 800-89 ASSURANCES CHECK", "CONDITIONAL TEST", "FIPS 186-3/SP 800-89 Assurances test successful"
            return(q);
        }
        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;
        }
예제 #32
0
        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);
        }
예제 #33
0
        // 5.4 pg 29

        /**
         * return true if the value r and s represent a DSA signature for
         * the passed in message (for standard DSA the message should be
         * a SHA-1 hash of the real message to be verified).
         */
        public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
        {
            BigInteger n = key.Parameters.N;

            // r and s should both in the range [1,n-1]
            if (r.SignValue < 1 || s.SignValue < 1 ||
                r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }

            BigInteger e = CalculateE(n, message);
            BigInteger c = s.ModInverse(n);

            BigInteger u1 = e.Multiply(c).Mod(n);
            BigInteger u2 = r.Multiply(c).Mod(n);

            ECPoint G = key.Parameters.G;
            ECPoint Q = ((ECPublicKeyParameters)key).Q;

            ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2);

            if (point.IsInfinity)
            {
                return(false);
            }

            /*
             * If possible, avoid normalizing the point (to save a modular inversion in the curve field).
             *
             * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
             * If the cofactor is known and small, we generate those possible field values and project each
             * of them to the same "denominator" (depending on the particular projective coordinates in use)
             * as the calculated point.X. If any of the projected values matches point.X, then we have:
             *     (point.X / Denominator mod p) mod n == r
             * as required, and verification succeeds.
             *
             * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
             * the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
             */
            ECCurve curve = point.Curve;

            if (curve != null)
            {
                BigInteger cofactor = curve.Cofactor;
                if (cofactor != null && cofactor.CompareTo(Eight) <= 0)
                {
                    ECFieldElement D = GetDenominator(curve.CoordinateSystem, point);
                    if (D != null && !D.IsZero)
                    {
                        ECFieldElement X = point.XCoord;
                        while (curve.IsValidFieldElement(r))
                        {
                            ECFieldElement R = curve.FromBigInteger(r).Multiply(D);
                            if (R.Equals(X))
                            {
                                return(true);
                            }
                            r = r.Add(n);
                        }
                        return(false);
                    }
                }
            }

            BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n);

            return(v.Equals(r));
        }