/// <summary> /// Returns k * point computed using the double and <see cref="PointAdd"/> algorithm. /// </summary> /// <param name="k"></param> /// <param name="point"></param> /// <returns></returns> public BigIntegerPoint ScalarMult(BigInteger k, BigIntegerPoint point) { if (EllipticCurveHelpers.MathMod(k, this.N) == 0 || point.IsEmpty()) { return(BigIntegerPoint.GetEmpty()); } if (k < 0) { return(this.ScalarMult(-k, this.NegatePoint(point))); } BigIntegerPoint result = BigIntegerPoint.GetEmpty(); BigIntegerPoint addend = point; while (k > 0) { if ((k & 1) > 0) { result = this.PointAdd(result, addend); } addend = this.PointAdd(addend, addend); k >>= 1; } return(result); }
public (BigInteger privateKey, BigIntegerPoint publicKey) GenerateKeyPair() { BigInteger privateKey = EllipticCurveHelpers.RandomIntegerBelow(this.Curve.N); BigIntegerPoint publicKey = this.Curve.ScalarMult(privateKey, this.Curve.G); return(privateKey, publicKey); }
public EllipticCurve(BigInteger a, BigInteger b, BigInteger p, BigIntegerPoint g, BigInteger n) { this.A = a; this.B = b; this.P = p; this.G = g; this.N = n; }
/// <summary> /// Returns <c>true</c> if the given point lies on the elliptic curve. /// </summary> /// <param name="point"></param> /// <returns></returns> public bool IsOnCurve(BigIntegerPoint point) { if (point.IsEmpty()) { return(true); } BigInteger x = point.X; BigInteger y = point.Y; return(EllipticCurveHelpers.MathMod(y * y - x * x * x - this.A * x - this.B, this.P) == 0); }
/// <summary> /// Returns -point. /// </summary> /// <param name="point"></param> /// <returns></returns> public BigIntegerPoint NegatePoint(BigIntegerPoint point) { if (point.IsEmpty()) { return(point); } BigInteger x = point.X; BigInteger y = point.Y; BigIntegerPoint result = new BigIntegerPoint(x, EllipticCurveHelpers.MathMod(-y, this.P)); return(result); }
/// <summary> /// Returns the result of lhs + rhs according to the group law. /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <returns></returns> public BigIntegerPoint PointAdd(BigIntegerPoint lhs, BigIntegerPoint rhs) { if (lhs.IsEmpty()) { return(rhs); } if (rhs.IsEmpty()) { return(lhs); } BigInteger x1 = lhs.X, y1 = lhs.Y; BigInteger x2 = rhs.X, y2 = rhs.Y; if (x1 == x2 && y1 != y2) { return(BigIntegerPoint.GetEmpty()); } BigInteger m; if (x1 == x2) { m = (3 * x1 * x1 + this.A) * this.InverseMod(2 * y1, this.P); } else { m = (y1 - y2) * this.InverseMod(x1 - x2, this.P); } BigInteger x3 = m * m - x1 - x2; BigInteger y3 = y1 + m * (x3 - x1); BigIntegerPoint result = new BigIntegerPoint(EllipticCurveHelpers.MathMod(x3, this.P), EllipticCurveHelpers.MathMod(-y3, this.P)); return(result); }
public BigIntegerPoint GetSharedkey(BigInteger privateKey, BigIntegerPoint publicKey) { return(this.Curve.ScalarMult(privateKey, publicKey)); }