public FastECPoint Multiply(FastInteger b) { if (b.Sign == -1) { throw new FormatException("The multiplicator cannot be negative"); } //b = b % Secp256k1.N; FastInteger exp = (b * 3) ^ b; FastECPoint result = FastECPoint.Infinity; FastECPoint affine = this.Normalize(); FastECPoint negative = affine.Negate(); int high = exp.BitsCount; FastInteger bit = FastInteger.One << high; for (int i = high; --i >= 0; bit >>= 1) { result = result.Twice(); if (!(exp & bit).IsZero) { result = result.Add(!(b & bit).IsZero ? negative : affine); } } result = result.Normalize(); return(result); }
public FastECPoint Negate() { FastECPoint r = (FastECPoint)Clone(); r._y = Secp256k1.FP - r._y; return(r); }
public FastECPoint Normalize() { if (this.Z == FastInteger.One || this.IsInfinity) { return(this); } var inverse = this.Z.ModInverse(Secp256k1.FP); var squareInverse = modP(inverse.Square()); var power3Inverse = modP(inverse * squareInverse); var x = modP(this.X * squareInverse); var y = modP(this.Y * power3Inverse); remodP(ref x); remodP(ref y); var result = new FastECPoint(x, y, this.IsInfinity); return(result); }
//if (Y == 0) // return POINT_AT_INFINITY //S = 4*X*Y^2 //M = 3*X^2 + a*Z^4 //X' = M^2 - 2*S //Y' = M*(S - X') - 8*Y^4 //Z' = 2*Y*Z //return (X', Y', Z') public FastECPoint Twice() { // (3M + 4S) if (this.Y.IsZero || this.IsInfinity) { return(FastECPoint.Infinity); } var y2 = modP(this.Y.Square()); var S = modP(this.X * y2 << 2); var M = this.X.Square(); M = modP(M + (M << 1)); var x = modP(M.Square() - (S << 1)); var y = modP(M * (S - x) - (y2.Square() << 3)); var z = modP(this.Z * (this.Y << 1)); var result = new FastECPoint(x, y, z, false); return(result); }
//U1 = X1*Z2^2 //U2 = X2*Z1^2 //S1 = Y1*Z2^3 //S2 = Y2*Z1^3 //if (U1 == U2) // if (S1 != S2) // return POINT_AT_INFINITY // else // return POINT_DOUBLE(X1, Y1, Z1) //H = U2 - U1 //R = S2 - S1 //X3 = R^2 - H^3 - 2*U1*H^2 //Y3 = R*(U1*H^2 - X3) - S1*H^3 //Z3 = H*Z1*Z2 //return (X3, Y3, Z3) public FastECPoint Add(FastECPoint q) { // (8M + 3S) if (this.IsInfinity) { return(q); } if (q.IsInfinity) { return(this); } var z2 = modP(this.Z.Square()); var z3 = modP(z2 * this.Z); var U2 = modP(q.X * z2); var S2 = modP(q.Y * z3); var H = U2 - this.X; var R = S2 - this.Y; if (H.IsZero) { if (!R.IsZero) { return(FastECPoint.Infinity); } return(this.Twice()); } var H2 = modP(H.Square()); var H3 = modP(H2 * H); var U1 = modP(this.X * H2); var X3 = modP(R.Square() - (H3 + (U1 << 1))); var Y3 = modP(R * (U1 - X3) - this.Y * H3); var Z3 = modP(H * this.Z); var result = new FastECPoint(X3, Y3, Z3, false); return(result); }
public FastECPoint Subtract(FastECPoint b) { return(Add(b.Negate())); }
public override ECPoint ECMultiplication(BigInteger factor) { FastECPoint result = Secp256k1.FG.Multiply(new FastInteger(factor.ToByteArray())); return(new ECPoint(new BigInteger(result.X.ToByteArray()), new BigInteger(result.Y.ToByteArray()))); }