Exemplo n.º 1
0
        public ECPoint Add(ECPoint other)
        {
            if (this.IsInifinity())
            {
                return(other);
            }
            if (other.IsInifinity())
            {
                return(this);
            }
            Number z1p2 = this._z2, z2p2 = other._z2, z1p3 = this._z3, z2p3 = other._z3;

            if (z1p2 == null)
            {
                this._z2 = z1p2 = _field.Multiply(_z, _z);
            }
            if (z2p2 == null)
            {
                other._z2 = z2p2 = _field.Multiply(other._z, other._z);
            }
            if (z1p3 == null)
            {
                this._z3 = z1p3 = _field.Multiply(z1p2, this._z);
            }
            if (z2p3 == null)
            {
                other._z3 = z2p3 = _field.Multiply(z2p2, other._z);
            }

            Number u1 = _field.Multiply(_x, z2p2);
            Number u2 = _field.Multiply(other._x, z1p2);
            Number H  = _field.Subtract(u2, u1);

            Number s1 = _field.Multiply(_y, z2p3);
            Number s2 = _field.Multiply(other._y, z1p3);
            Number r  = _field.Subtract(s2, s1);

            if (H.IsZero())
            {
                if (r.IsZero())
                {
                    return(Double());
                }
                return(_field.GetInfinityPoint(_group));
            }

            Number H2 = _field.Multiply(H, H);
            Number H3 = _field.Multiply(H2, H);
            Number X  = _field.Subtract(_field.Subtract(_field.Multiply(r, r), H3), _field.Multiply(_field.Add(u1, u1), H2));
            Number Y  = _field.Subtract(_field.Multiply(r, _field.Subtract(_field.Multiply(u1, H2), X)), _field.Multiply(s1, H3));
            Number Z  = _field.Multiply(_field.Multiply(_z, other._z), H);

            return(new ECPoint(_group, X, Y, Z));
        }
Exemplo n.º 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();
            }
        }
Exemplo n.º 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 ();
			}
		}