Beispiel #1
0
        static ECDomainParameters Create(Number a, Number b, Number gX, Number gY, Number order, uint h, IFiniteField ff, Uri uri)
        {
            ECGroup group     = new ECGroup(ff.ToElement(a), ff.ToElement(b), ff.Modulus, ff);
            ECPoint basePoint = new ECPoint(group, ff.ToElement(gX), ff.ToElement(gY), ff.ToElement(Number.One));

            return(new ECDomainParameters(group, basePoint, order, h, (uint)ff.Modulus.BitCount(), new Classical(order), uri));
        }
Beispiel #2
0
        /// <summary>バイト配列より点を作成する (SEC1, 2.3.4)</summary>
        public ECPoint(ECGroup group, byte[] data)
        {
            _group = group;
            _field = group.FiniteField;
            switch (data[0])
            {
            case 0: {                     // 無限遠点
                ECPoint tmp = _field.GetInfinityPoint(_group);
                _x = tmp._x;
                _y = tmp._y;
                _z = tmp._z;
                return;
            }

            case 2:
            case 3: {                     // 点圧縮済みデータ
                int keyBits  = group.P.BitCount();
                int keyBytes = (keyBits >> 3) + ((keyBits & 7) == 0 ? 0 : 1);
                if (data.Length != keyBytes + 1)
                {
                    throw new ArgumentException();
                }
                Number x  = _field.ToElement(new Number(data, 1, keyBytes, false));
                Number y2 = _field.Add(_field.Multiply(_field.Add(_field.Multiply(x, x), _group.A), x), _group.B);                             // (x^2 + a)*x + b
                Number y  = _field.Sqrt(y2);
                if (_field.ToNormal(y).GetBit(0) != data[0] - 2)
                {
                    y = _field.Modulus - y;
                }
                _x = x;
                _y = y;
                _z = _field.ToElement(Number.One);
                return;
            }

            case 4: {                     // 非圧縮データ
                int keyBits  = group.P.BitCount();
                int keyBytes = (keyBits >> 3) + ((keyBits & 7) == 0 ? 0 : 1);
                _x = _field.ToElement(new Number(data, 1, keyBytes, false));
                _y = _field.ToElement(new Number(data, 1 + keyBytes, keyBytes, false));
                _z = _field.ToElement(Number.One);
                return;
            }

            default:
                throw new ArgumentException();
            }
        }
Beispiel #3
0
		/// <summary>バイト配列より点を作成する (SEC1, 2.3.4)</summary>
		public ECPoint (ECGroup group, byte[] data)
		{
			_group = group;
			_field = group.FiniteField;
			switch (data[0]) {
				case 0: { // 無限遠点
					ECPoint tmp = _field.GetInfinityPoint (_group);
					_x = tmp._x;
					_y = tmp._y;
					_z = tmp._z;
					return;
				}
				case 2:
				case 3: { // 点圧縮済みデータ
					int keyBits = group.P.BitCount ();
					int keyBytes = (keyBits >> 3) + ((keyBits & 7) == 0 ? 0 : 1);
					if (data.Length != keyBytes + 1)
						throw new ArgumentException ();
					Number x = _field.ToElement (new Number (data, 1, keyBytes, false));
					Number y2 = _field.Add (_field.Multiply (_field.Add (_field.Multiply (x, x), _group.A), x), _group.B); // (x^2 + a)*x + b
					Number y = _field.Sqrt (y2);
					if (_field.ToNormal (y).GetBit (0) != data[0] - 2)
						y = _field.Modulus - y;
					_x = x;
					_y = y;
					_z = _field.ToElement (Number.One);
					return;
				}
				case 4: { // 非圧縮データ
					int keyBits = group.P.BitCount ();
					int keyBytes = (keyBits >> 3) + ((keyBits & 7) == 0 ? 0 : 1);
					_x = _field.ToElement (new Number (data, 1, keyBytes, false));
					_y = _field.ToElement (new Number (data, 1 + keyBytes, keyBytes, false));
					_z = _field.ToElement (Number.One);
					return;
				}
				default:
					throw new ArgumentException ();
			}
		}
Beispiel #4
0
        /// <summary>
        /// TODO: 未実装のValidationステップを実装する
        /// </summary>
        public bool Validate()
        {
            IFiniteField ff = _group.FiniteField;

            // Step1: Check that p is an odd prime
            // Step2: Check that a,b,Gx and Gy are integers in the interval [0, p - 1]
            ECPoint ExportedG = _G.Export();
            Number  Gx        = ff.ToElement(ExportedG.X);
            Number  Gy        = ff.ToElement(ExportedG.Y);

            if (A > P || B > P || Gx > P || Gy > P)
            {
                return(false);
            }

            // Step3: Check that 4*a^3 + 27*b^2 != 0 (mod p)
            Number Apow3 = ff.Multiply(A, ff.Multiply(A, A));
            Number Bpow2 = ff.Multiply(B, B);
            Number ret   = ff.Add(ff.Multiply(ff.ToElement(Number.Four), ff.ToElement(Apow3)), ff.Multiply(ff.ToElement(Number.TwentySeven), Bpow2));

            if (ret.IsZero())
            {
                return(false);
            }

            // Step4: Gy^2 = Gx^3 + a*Gx + b
            Number aGx   = ff.Multiply(A, Gx);
            Number Xpow3 = ff.Multiply(Gx, ff.Multiply(Gx, Gx));
            Number Ypow2 = ff.Multiply(Gy, Gy);

            ret = ff.Add(Xpow3, ff.Add(aGx, B));
            if (ret.CompareTo(Ypow2) != 0)
            {
                return(false);
            }

            // Step5: Check that n is prime.
            // Step6: Check that h <= 4, and that h = (sqrt(p)+1)^2 / n

            // Step7: Check that nG = O
            ECPoint nG = _G.Multiply(N).Export();

            if (!nG.IsInifinity())
            {
                return(false);
            }

            // Step8: Check that q^B != 1 (mod n) for any 1 <= B <= 20, and that nh != p
            Number    p = Number.One;
            Classical c = new Classical(N);

            for (int i = 0; i <= 20; i++)
            {
                p = c.Multiply(p, P);
                if (p.IsOne())
                {
                    return(false);
                }
            }
            if (c.Multiply(N, new Number(new uint[] { H }, 1)).CompareTo(P) == 0)
            {
                return(false);
            }

            return(true);
        }
Beispiel #5
0
        internal byte[] SignHash(byte[] hash, byte[] randomK)
#endif
        {
            if (hash == null)
            {
                throw new ArgumentNullException();
            }
            if (hash.Length == 0)
            {
                throw new ArgumentException();
            }
            if (_params.D == null && _params.Q == null)
            {
                _params.CreateNewPrivateKey();
            }
            if (_params.D == null)
            {
                throw new CryptographicException();
            }

            Number       r, s, k;
            IFiniteField field    = _params.Domain.FieldN;
            int          keyBytes = (int)((_params.Domain.Bits >> 3) + ((_params.Domain.Bits & 7) == 0 ? 0U : 1U));

            byte[] raw = new byte[keyBytes << 1];
            Number e   = HashToNumber(hash);

            do
            {
                do
                {
                    // Step.1
#if TEST
                    k = randomK == null
                                                ? k = Number.CreateRandomElement(_params.Domain.N)
                                                : new Number(randomK, false);
#else
                    k = Number.CreateRandomElement(_params.Domain.N);
#endif

                    // Step.2
                    ECPoint tmp = _params.Domain.G.Multiply(k).Export();

                    // Step.3
                    r = tmp.X % _params.Domain.N;
                    if (!r.IsZero())
                    {
                        r.CopyToBigEndian(raw, 0, keyBytes);
                        break;
                    }
                } while (true);

                // Step.4
                k = field.Invert(field.ToElement(k));

                // Step.6
                r = field.ToElement(r);
                e = field.ToElement(e);
                s = field.Multiply(k, field.Add(e, field.Multiply(r, field.ToElement(_params.D))));
                if (!s.IsZero())
                {
                    s = field.ToNormal(s);
                    s.CopyToBigEndian(raw, raw.Length >> 1, keyBytes);
                    break;
                }
            } while (true);

            return(raw);
        }
Beispiel #6
0
        public bool VerifyHash(byte[] hash, byte[] sig)
        {
            if (sig.Length != (_params.Domain.Bits >> 2) + ((_params.Domain.Bits & 7) == 0 ? 0 : 2))
            {
                throw new ArgumentException();
            }
            if (hash.Length == 0)
            {
                throw new ArgumentException();
            }
            if (_params.Q == null && _params.D != null)
            {
                _params.CreatePublicKeyFromPrivateKey();
            }
            if (_params.Q == null)
            {
                throw new CryptographicException();
            }

            int          halfLen = sig.Length >> 1;
            Number       r       = new Number(sig, 0, halfLen, false);
            Number       s       = new Number(sig, halfLen, halfLen, false);
            Number       e       = HashToNumber(hash);
            IFiniteField field   = _params.Domain.FieldN;

            if (r >= _params.Domain.N || s >= _params.Domain.N)
            {
                return(false);
            }

            // Step.1
            e = field.ToElement(e);
            s = field.ToElement(s);
            Number r2 = field.ToElement(r);

            // Step.2
            Number w = field.Invert(s);

            // Step.3
            Number u1 = field.ToNormal(field.Multiply(e, w));
            Number u2 = field.ToNormal(field.Multiply(r2, w));

            // Step.4
            //ECPoint X = _params.Domain.G.Multiply (u1).Add (_params.Q.Multiply (u2));
            ECPoint X;

            if (u1.IsZero())
            {
                X = _params.Domain.FieldN.GetInfinityPoint(_params.Domain.Group).Add(_params.Q.Multiply(u2));
            }
            else
            {
                X = ECPoint.MultiplyAndAdd(_params.Domain.G, u1, _params.Q, u2);
            }

            // Step.5
            if (X.IsInifinity())
            {
                return(false);
            }
            X = X.Export();

            // Step.6
            Number v = X.X % _params.Domain.N;

            return(r.CompareTo(v) == 0);
        }