{"id":108,"date":"2020-07-09T20:56:20","date_gmt":"2020-07-09T20:56:20","guid":{"rendered":"https:\/\/michaeljohnsteiner.com\/?p=108"},"modified":"2020-07-27T04:13:47","modified_gmt":"2020-07-27T04:13:47","slug":"rngjittersource-cs","status":"publish","type":"post","link":"https:\/\/michaeljohnsteiner.com\/index.php\/2020\/07\/09\/rngjittersource-cs\/","title":{"rendered":"RngJitterSource.cs"},"content":{"rendered":"\n<p>CPU RAM Jitter Driven RNG Data Source<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Diagnostics;\nusing System.Security.Cryptography;\nusing System.Threading;\npublic class RngJitterSource : RandomNumberGenerator\n{\n    \/\/\/ &lt;summary>\n    \/\/\/     Recalculate buffer every 1000 milliseconds\n    \/\/\/ &lt;\/summary>\n    private const int ReSecureThresholdBf = 1000;\n    private readonly SHA3ModInt _algorithm;\n    private readonly object     _cacheLock = new object();\n    private readonly int        _moveSize;\n    \/\/\/ &lt;summary>\n    \/\/\/     Just in case you need access to the underlying data\n    \/\/\/ &lt;\/summary>\n    public readonly JitterEx Jitter;\n    private readonly Stopwatch tmr;\n    private          byte[]    _cacheBuffer;\n    private          int       _cacheSize;\n    private volatile int       _ptr;\n    private volatile int       BytesRemainingInCache;\n    \/\/\/ &lt;summary>\n    \/\/\/     If you want to use this as a flat memory pool\n    \/\/\/     Use in conjunction with DataReady -- DataReady.WaitOne(); -- use data\n    \/\/\/ &lt;\/summary>\n    public volatile byte[] Cache;\n    public  int    cacheFills;\n    private Thread CacheThread;\n    \/\/\/ &lt;summary>\n    \/\/\/     See Cache above\n    \/\/\/ &lt;\/summary>\n    public AutoResetEvent DataReady = new AutoResetEvent(false);\n    private bool Filled;\n    public  int  ResecureCount;\n    public RngJitterSource() : this(1024 * 1024, 1024, 256, 4)\n    {\n    }\n    public RngJitterSource(int cacheSize) : this(cacheSize, 1024, 256, 4)\n    {\n    }\n    public RngJitterSource(int cacheSize, int seedSize) : this(cacheSize, seedSize, 256, 4)\n    {\n    }\n    public RngJitterSource(int cacheSize, int seedSize, int sha3Size) : this(cacheSize, seedSize, sha3Size, 4)\n    {\n    }\n    public RngJitterSource(int cacheSize, int seedSize, int sha3Size, int sha3Rounds)\n    {\n        _cacheSize   = cacheSize;\n        Jitter       = new JitterEx();\n        _cacheBuffer = new byte[seedSize];\n        Jitter.GetBytes(_cacheBuffer);\n        Cache                 = new byte[_cacheSize];\n        _ptr                  = 0;\n        BytesRemainingInCache = 0;\n        _algorithm            = new SHA3ModInt(sha3Size, sha3Rounds);\n        _moveSize             = _algorithm.ComputeHash(2.GetBytes()).Length;\n        Filled                = false;\n        tmr                   = new Stopwatch();\n        CacheThread           = new Thread(KeepFullCache) {Priority = ThreadPriority.Highest};\n        CacheThread.Start();\n    }\n    public void Abort()\n    {\n        CacheThread.Abort();\n    }\n    protected override void Dispose(bool disposing)\n    {\n        _algorithm.Dispose();\n    }\n    public override void GetBytes(byte[] data)\n    {\n        if (data.Length > _cacheSize)\n        {\n            _cacheSize            = data.Length;\n            Cache                 = new byte[_cacheSize];\n            _ptr                  = 0;\n            BytesRemainingInCache = 0;\n            if (CacheThread.IsAlive)\n                CacheThread.Abort();\n            DataReady   = new AutoResetEvent(false);\n            CacheThread = new Thread(KeepFullCache) {Priority = ThreadPriority.Highest};\n            CacheThread.Start();\n        }\n        while (_ptr &lt; data.Length)\n            Thread.Sleep(10);\n        DataReady.WaitOne();\n        Buffer.BlockCopy(Cache, _ptr - data.Length, data, 0, data.Length);\n        _ptr                  -= data.Length;\n        BytesRemainingInCache -= data.Length;\n    }\n    private void KeepFullCache()\n    {\n        while (true)\n            if (BytesRemainingInCache &lt; _moveSize)\n                lock (_cacheLock)\n                {\n                    var moveSize = _moveSize;\n                    cacheFills++;\n                    var bufferFills = 0;\n                    tmr.Start();\n                    while (true)\n                    {\n                        bufferFills++;\n                        if (tmr.Elapsed.TotalMilliseconds >= ReSecureThresholdBf)\n                        {\n                            Jitter.GetBytes(_cacheBuffer);\n                            tmr.Restart();\n                            ResecureCount++;\n                        }\n                        var remainingBytesToMove = _cacheSize - _ptr;\n                        if (remainingBytesToMove &lt; moveSize)\n                            moveSize = remainingBytesToMove;\n                        if (remainingBytesToMove &lt;= 0 || _ptr >= _cacheSize)\n                            break;\n                        _cacheBuffer = _algorithm.ComputeHash(_cacheBuffer);\n                        Buffer.BlockCopy(_cacheBuffer, 0, Cache, _ptr, moveSize);\n                        _ptr += moveSize;\n                    }\n                    tmr.Stop();\n                    _ptr                  = _cacheSize;\n                    BytesRemainingInCache = _cacheSize;\n                    DataReady.Set();\n                }\n            else\n                DataReady.Set();\n    }\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>CPU RAM Jitter Driven RNG Data Source<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[42,15,47,44,40,49,45,48],"_links":{"self":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/108"}],"collection":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/comments?post=108"}],"version-history":[{"count":2,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/108\/revisions"}],"predecessor-version":[{"id":111,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/108\/revisions\/111"}],"wp:attachment":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/media?parent=108"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/categories?post=108"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/tags?post=108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}