public BigInteger[] GenerateSignature(byte[] message) { if (privateKey == null) { throw new InvalidOperationException(); } BigInteger e = CalculateE(curve.N, message); BigInteger d = new BigInteger(privateKey.Reverse().Concat(new byte[1]).ToArray()); BigInteger r, s; using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) { do { BigInteger k; do { do { k = rng.NextBigInteger(curve.N.GetBitLength()); }while (k.Sign == 0 || k.CompareTo(curve.N) >= 0); ECPoint p = ECPoint.Multiply(curve.G, k); BigInteger x = p.X.Value; r = x.Mod(curve.N); }while (r.Sign == 0); s = (k.ModInverse(curve.N) * (e + d * r)).Mod(curve.N); if (s > curve.N / 2) { s = curve.N - s; } }while (s.Sign == 0); } return(new BigInteger[] { r, s }); }
public ECFieldElement Sqrt() { if (curve.Q.TestBit(1)) { ECFieldElement z = new ECFieldElement(BigInteger.ModPow(Value, (curve.Q >> 2) + 1, curve.Q), curve); return(z.Square().Equals(this) ? z : null); } BigInteger qMinusOne = curve.Q - 1; BigInteger legendreExponent = qMinusOne >> 1; if (BigInteger.ModPow(Value, legendreExponent, curve.Q) != 1) { return(null); } BigInteger u = qMinusOne >> 2; BigInteger k = (u << 1) + 1; BigInteger Q = this.Value; BigInteger fourQ = (Q << 2).Mod(curve.Q); BigInteger U, V; do { BigInteger P; do { using (var rng = new RNGCryptoServiceProvider()) P = rng.NextBigInteger(curve.Q.GetBitLength()); }while (P >= curve.Q || BigInteger.ModPow(P * P - fourQ, legendreExponent, curve.Q) != qMinusOne); BigInteger[] result = FastLucasSequence(curve.Q, P, Q, k); U = result[0]; V = result[1]; if ((V * V).Mod(curve.Q) == fourQ) { if (V.TestBit(0)) { V += curve.Q; } V >>= 1; Debug.Assert((V * V).Mod(curve.Q) == Value); return(new ECFieldElement(V, curve)); } }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return(null); }