private void CheckOnCurve(EllipticCurvePoint a) { if (!curve.IsOnCurve(a)) { throw new ArgumentException("Point not on curve"); } }
public EllipticCurvePoint ScalarMult(BigInteger k, EllipticCurvePoint a) { CheckOnCurve(a); if (k.ModulusGF(curve.N) == 0 || EllipticCurvePoint.IsInfinity(a)) { return(EllipticCurvePoint.InfinityPoint); } if (k < 0) { return(ScalarMult(-k, NegativePoint(a))); } EllipticCurvePoint res = EllipticCurvePoint.InfinityPoint; EllipticCurvePoint temp = a; while (k != 0) { if ((k & 1) == 1) { res = Add(res, temp); } temp = Twice(temp); k >>= 1; } return(res); }
public EllipticCurve(BigInteger a, BigInteger b, BigInteger p, BigInteger n, uint m, EllipticCurvePoint basePoint = null) { A = a; B = b; P = p; N = n; M = m; this.basePoint = basePoint; }
public bool IsValidPrivateKey(BigInteger privateKey, EllipticCurvePoint publicKey) { EllipticCurvePoint p = NegativePoint(ScalarMult(privateKey, curve.BasePoint)); if (EllipticCurvePoint.IsInfinity(p)) { return(false); } return(p.X == publicKey.X && p.Y == publicKey.Y); }
public (BigInteger, EllipticCurvePoint) GenenrateKeyPair() { if (!Initialized) { throw new Exception("Elliptic curve wasn't initialized"); } BigInteger d = GetRandomIntegerFromField(); EllipticCurvePoint p = NegativePoint(ScalarMult(d, curve.BasePoint)); return(d, p); }
public EllipticCurvePoint GenerateBasePoint() { EllipticCurvePoint result; do { result = GeneratePoint(); }while (!EllipticCurvePoint.IsInfinity(ScalarMult(curve.N, result))); CheckOnCurve(result); return(result); }
public EllipticCurvePoint NegativePoint(EllipticCurvePoint a) { CheckOnCurve(a); if (EllipticCurvePoint.IsInfinity(a)) { return(a); } var result = new EllipticCurvePoint(a.X, a.X.AddGF(a.Y)); CheckOnCurve(a); return(result); }
public bool IsOnCurve(EllipticCurvePoint point) { if (EllipticCurvePoint.IsInfinity(point)) { return(true); } BigInteger y = point.Y; BigInteger x = point.X; BigInteger lhs = y.SquareGF(P).AddGF(x.MultGF(y, P)); BigInteger rhs = x.SquareGF(P).MultGF(x, P).AddGF(x.SquareGF(P).MultGF(A, P)).AddGF(B); return(lhs == rhs); }
public EllipticCurvePoint Twice(EllipticCurvePoint a) { if (EllipticCurvePoint.IsInfinity(a)) { return(a); } BigInteger sigma = a.X.InverseGF(curve.P).MultGF(a.Y, curve.P).AddGF(a.X); BigInteger x = sigma.SquareGF(curve.P).AddGF(sigma).AddGF(curve.A); BigInteger y = a.X.SquareGF(curve.P).AddGF(sigma.AddGF(BigInteger.One).MultGF(x, curve.P)); var result = new EllipticCurvePoint(x, y); //CheckOnCurve(result); return(result); }
public EllipticCurvePoint GeneratePoint() { EllipticCurvePoint result = EllipticCurvePoint.InfinityPoint; BigInteger u, z; int k; do { u = GetRandomIntegerFromField(); BigInteger w = u.SquareGF(curve.P).MultGF(u, curve.P).AddGF(u.SquareGF(curve.P).MultGF(curve.A, curve.P)).AddGF(curve.B); k = SolveQuadraticEquation(u, w, out z); }while (k == 0); result = new EllipticCurvePoint(u, z); CheckOnCurve(result); return(result); }
public (BigInteger, BigInteger) PreComputedSign() { if (EllipticCurvePoint.IsInfinity(curve.BasePoint)) { throw new Exception("Base point uninitialized"); } while (true) { BigInteger e = GetRandomIntegerFromField(); EllipticCurvePoint r = ScalarMult(e, curve.BasePoint); if (!EllipticCurvePoint.IsInfinity(r) && r.X != 0) { return(e, r.X); } } }
public bool IsValidPublicKey(EllipticCurvePoint publicKey) { if (EllipticCurvePoint.IsInfinity(publicKey)) { return(false); } if (publicKey.X >= curve.P || publicKey.Y >= curve.P || publicKey.X * publicKey.Y == 0) { return(false); } if (!curve.IsOnCurve(publicKey)) { return(false); } return(EllipticCurvePoint.IsInfinity(ScalarMult(curve.N, publicKey))); }
public bool VerifySign(byte[] message, EllipticCurvePoint publicKey, BigInteger r, BigInteger s, HashAlgorithm hashAlgorithm) { if (!IsValidPublicKey(publicKey)) { throw new Exception("Public key is invalid"); } if (r >= curve.N || s >= curve.N || r <= 0 || s <= 0) { return(false); } byte[] hash = hashAlgorithm.ComputeHash(message); BigInteger hashInt = TransformHash(hash); var R = Add(ScalarMult(s, curve.BasePoint), ScalarMult(r, publicKey)); var y = R.X.MultGF(hashInt, curve.P); var r1 = y.Seek(curve.N.GetBitCount() - 1); return(r1 == r); }
public EllipticCurvePoint Add(EllipticCurvePoint a, EllipticCurvePoint b) { if (EllipticCurvePoint.IsInfinity(a)) { CheckOnCurve(b); return(b); } if (EllipticCurvePoint.IsInfinity(b)) { CheckOnCurve(a); return(a); } CheckOnCurve(a); CheckOnCurve(b); BigInteger x, y; if (a.X == b.X) { if (a.Y != b.Y || a.X == BigInteger.Zero) { return(EllipticCurvePoint.InfinityPoint); } return(Twice(a)); } else { BigInteger lambda = a.X.AddGF(b.X).InverseGF(curve.P).MultGF(a.Y.AddGF(b.Y), curve.P); x = lambda.SquareGF(curve.P).AddGF(lambda).AddGF(a.X).AddGF(b.X).AddGF(curve.A); y = a.X.AddGF(x).MultGF(lambda, curve.P).AddGF(x).AddGF(a.Y); } var result = new EllipticCurvePoint(x, y); CheckOnCurve(result); return(result); }
public static bool IsInfinity(EllipticCurvePoint point) => point == InfinityPoint;
public (BigInteger, BigInteger) SignMessage(byte[] message, BigInteger privateKey, EllipticCurvePoint publicKey, HashAlgorithm hashAlgorithm) { if (!IsValidPrivateKey(privateKey, publicKey)) { throw new Exception("Private key is invalid"); } byte[] hash = hashAlgorithm.ComputeHash(message); BigInteger hashInt = TransformHash(hash); BigInteger e, fe, r, s; do { (e, fe) = PreComputedSign(); r = fe.MultGF(hashInt, curve.P).Seek(curve.N.GetBitCount() - 1); s = (r * privateKey + e) % curve.N;//r.MultGF(privateKey, curve.P).AddGF(e).ModulusGF(curve.N); } while (r == 0 || s == 0); return(r, s); }