public ECC521Point Multiply(BigInteger b) { if (b.Sign == -1) { throw new FormatException("The multiplicator cannot be negative"); } if (b >= OrderN) { b %= OrderN; } BigInteger exp = (b * 3) ^ b; ECC521Point result = ECC521Point.Infinity; ECC521Point affine = this.Normalize(); ECC521Point negative = affine.Negate(); int high = exp <= 0 ? 0 : (int)Math.Floor(BigInteger.Log(exp, 2)); BigInteger bit = BigInteger.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 ECC521Point Negate() { ECC521Point r = (ECC521Point)Clone(); r._y = P - r._y; return(r); }
public ECC521Point Normalize() { if (this.Z == BigInteger.One || this.IsInfinity) { return(this); } var inverse = this.Z.ModInverse(P); 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 ECC521Point(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 = 3(X - Z^2) * (X + Z^2) //X' = M^2 - 2*S //Y' = M*(S - X') - 8*Y^4 //Z' = 2*Y*Z //return (X', Y', Z') public ECC521Point Twice() { // (4M + 4S) if (this.Y.IsZero || this.IsInfinity) { return(ECC521Point.Infinity); } var y2 = modP(this.Y.Square()); var z2 = modP(this.Z.Square()); var S = modP(this.X * y2 << 2); var M = (this.X - z2) * (this.X + z2); 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 ECC521Point(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 ECC521Point Add(ECC521Point 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(ECC521Point.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 ECC521Point(X3, Y3, Z3, false); return(result); }
public ECC521Point Subtract(ECC521Point b) { return(Add(b.Negate())); }
public override ECPoint ECMultiplication(BigInteger factor) { ECC521Point point = ECC521Point.G.Multiply(factor); return(new ECPoint(point.X, point.Y, point.IsInfinity)); }