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)); }
/// <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(); } }
/// <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 (); } }