<commit_before>﻿using NBitcoin.DataEncoders;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using NBitcoin.Protocol;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
#if !HAS_SPAN
using NBitcoin.BouncyCastle.Math;
#endif
using System.Runtime.InteropServices;
#if !NOSOCKET
using System.Net.Sockets;
#endif
#if WINDOWS_UWP
using System.Net.Sockets;
using Windows.Networking;
using Windows.Networking.Connectivity;
#endif

namespace NBitcoin
{
	public static class Extensions
	{
#if HAS_SPAN
		internal static Crypto.ECDSASignature Sign(this Secp256k1.ECPrivKey key, uint256 h, bool enforceLowR)
		{
			return new Crypto.ECDSASignature(key.Sign(h, enforceLowR, out _));
		}
		internal static Secp256k1.SecpECDSASignature Sign(this Secp256k1.ECPrivKey key, uint256 h, bool enforceLowR, out int recid)
		{
			Span<byte> hash = stackalloc byte[32];
			h.ToBytes(hash);
			byte[] extra_entropy = null;
			Secp256k1.RFC6979NonceFunction nonceFunction = null;
			Span<byte> vchSig = stackalloc byte[Secp256k1.SecpECDSASignature.MaxLength];
			Secp256k1.SecpECDSASignature sig;
			uint counter = 0;
			bool ret = key.TrySignECDSA(hash, null, out recid, out sig);
			// Grind for low R
			while (ret && sig.r.IsHigh && enforceLowR)
			{
				if (extra_entropy == null || nonceFunction == null)
				{
					extra_entropy = new byte[32];
					nonceFunction = new Secp256k1.RFC6979NonceFunction(extra_entropy);
				}
				Utils.ToBytes(++counter, true, extra_entropy.AsSpan());
				ret = key.TrySignECDSA(hash, nonceFunction, out recid, out sig);
			}
			return sig;
		}
#endif
		/// <summary>
		/// Deriving an HDKey is normally time consuming, this wrap the IHDKey in a new HD object which can cache derivations
		/// </summary>
		/// <param name="hdkey">The hdKey to wrap</param>
		/// <returns>An hdkey which cache derivations, of the parameter if it is already itself a cache</returns>
		public static IHDKey AsHDKeyCache(this IHDKey hdkey)
		{
			if (hdkey == null)
				throw new ArgumentNullException(nameof(hdkey));<commit_msg>Save a few allocation when signing with enforceLowR<commit_after>﻿using NBitcoin.DataEncoders;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using NBitcoin.Protocol;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
#if !HAS_SPAN
using NBitcoin.BouncyCastle.Math;
#endif
using System.Runtime.InteropServices;
#if !NOSOCKET
using System.Net.Sockets;
#endif
#if WINDOWS_UWP
using System.Net.Sockets;
using Windows.Networking;
using Windows.Networking.Connectivity;
#endif

namespace NBitcoin
{
	public static class Extensions
	{
#if HAS_SPAN
		internal static Crypto.ECDSASignature Sign(this Secp256k1.ECPrivKey key, uint256 h, bool enforceLowR)
		{
			return new Crypto.ECDSASignature(key.Sign(h, enforceLowR, out _));
		}
		internal static Secp256k1.SecpECDSASignature Sign(this Secp256k1.ECPrivKey key, uint256 h, bool enforceLowR, out int recid)
		{
			Span<byte> hash = stackalloc byte[32];
			h.ToBytes(hash);
			byte[] extra_entropy = null;
			Secp256k1.RFC6979NonceFunction nonceFunction = null;
			Span<byte> vchSig = stackalloc byte[Secp256k1.SecpECDSASignature.MaxLength];
			Secp256k1.SecpECDSASignature sig;
			uint counter = 0;
			bool ret = key.TrySignECDSA(hash, null, out recid, out sig);
			if (extra_entropy == null || nonceFunction == null)
			{
				extra_entropy = new byte[32];
				nonceFunction = new Secp256k1.RFC6979NonceFunction(extra_entropy);
			}
			// Grind for low R
			while (ret && sig.r.IsHigh && enforceLowR)
			{
				Utils.ToBytes(++counter, true, extra_entropy.AsSpan());
				ret = key.TrySignECDSA(hash, nonceFunction, out recid, out sig);
			}
			return sig;
		}
#endif
		/// <summary>
		/// Deriving an HDKey is normally time consuming, this wrap the IHDKey in a new HD object which can cache derivations
		/// </summary>
		/// <param name="hdkey">The hdKey to wrap</param>
		/// <returns>An hdkey which cache derivations, of the parameter if it is already itself a cache</returns>
		public static IHDKey AsHDKeyCache(this IHDKey hdkey)
		{
			if (hdkey == null)
				throw new ArgumentNullException(nameof(hdkey));
{'fraction_non_alphanumeric': 0.10118356927361337, 'fraction_numerical': 0.021814806219540496, 'mean_word_length': 4.435056746532156, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6390604', 'n_tokens_mistral': 1681, 'n_tokens_neox': 1479, 'n_words': 392}