private static BigInteger DeterministicGenerateK(Curve curve, byte[] hash, BigInteger d, SignDelegate checkSign, uint nonce) { if (nonce > 0) { hash = SHA256.Create().HashAndDispose(hash.Concat(new byte[nonce])); } Assert.Equal(hash.Length, 32, "Hash must be 256 bit"); var x = d.ToBuffer(32); var key = new byte[32].Fill((byte)0); var value = new byte[32].Fill((byte)1); // Step D key = new HMACSHA256(key).HashAndDispose(value.Concat(new[] { (byte)0 }, x, hash)); // Step E value = new HMACSHA256(key).HashAndDispose(value); // Step F key = new HMACSHA256(key).HashAndDispose(value.Concat(new[] { (byte)1 }, x, hash)); // Step G value = new HMACSHA256(key).HashAndDispose(value); // Step H1/H2a, ignored as tlen == qlen (256 bit) // Step H2b value = new HMACSHA256(key).HashAndDispose(value); var t = BigInteger.FromBuffer(value); // Step H3, repeat until t is within the interval [1, n - 1] while ((t.Sign <= 0) || (t.CompareTo(curve.N) >= 0) || !checkSign(t)) { key = new HMACSHA256(key).HashAndDispose(value.Concat(new[] { (byte)0 })); value = new HMACSHA256(key).HashAndDispose(value); // Step H1/H2a, again, ignored as tlen == qlen (256 bit) // Step H2b again value = new HMACSHA256(key).HashAndDispose(value); t = BigInteger.FromBuffer(value); } return(t); }