< Summary

Information
Class: Renci.SshNet.Security.Org.BouncyCastle.Crypto.Prng.DigestRandomGenerator
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\crypto\prng\DigestRandomGenerator.cs
Line coverage
88%
Covered lines: 63
Uncovered lines: 8
Coverable lines: 71
Total lines: 117
Line coverage: 88.7%
Branch coverage
83%
Covered branches: 5
Total branches: 6
Branch coverage: 83.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
AddSeedMaterial(...)100%1100%
AddSeedMaterial(...)100%1100%
NextBytes(...)100%1100%
NextBytes(...)100%4100%
CycleSeed()100%10%
GenerateState()50%270%
DigestAddCounter(...)100%1100%
DigestUpdate(...)100%1100%
DigestDoFinal(...)100%1100%

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\crypto\prng\DigestRandomGenerator.cs

#LineLine coverage
 1using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Utilities;
 2
 3namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Prng
 4{
 5  internal class DigestRandomGenerator
 6    : IRandomGenerator
 7  {
 8    private const long CYCLE_COUNT = 10;
 9
 10    private long  stateCounter;
 11    private long  seedCounter;
 12    private IDigest  digest;
 13    private byte[]  state;
 14    private byte[]  seed;
 15
 1016    public DigestRandomGenerator(
 1017      IDigest digest)
 1018    {
 1019      this.digest = digest;
 20
 1021      this.seed = new byte[digest.GetDigestSize()];
 1022      this.seedCounter = 1;
 23
 1024      this.state = new byte[digest.GetDigestSize()];
 1025      this.stateCounter = 1;
 1026    }
 27
 28    public void AddSeedMaterial(
 29      byte[] inSeed)
 1030    {
 1031      lock (this)
 1032      {
 1033        DigestUpdate(inSeed);
 1034        DigestUpdate(seed);
 1035        DigestDoFinal(seed);
 1036      }
 1037    }
 38
 39    public void AddSeedMaterial(
 40      long rSeed)
 1041    {
 1042      lock (this)
 1043      {
 1044        DigestAddCounter(rSeed);
 1045        DigestUpdate(seed);
 1046        DigestDoFinal(seed);
 1047      }
 1048    }
 49
 50    public void NextBytes(
 51      byte[] bytes)
 952    {
 953      NextBytes(bytes, 0, bytes.Length);
 954    }
 55
 56    public void NextBytes(
 57      byte[]  bytes,
 58      int    start,
 59      int    len)
 960    {
 961      lock (this)
 962      {
 963        int stateOff = 0;
 64
 965        GenerateState();
 66
 967        int end = start + len;
 89468        for (int i = start; i < end; ++i)
 43869        {
 43870          if (stateOff == state.Length)
 971          {
 972            GenerateState();
 973            stateOff = 0;
 974          }
 43875          bytes[i] = state[stateOff++];
 43876        }
 977      }
 978    }
 79
 80    private void CycleSeed()
 081    {
 082      DigestUpdate(seed);
 083      DigestAddCounter(seedCounter++);
 084      DigestDoFinal(seed);
 085    }
 86
 87    private void GenerateState()
 1888    {
 1889      DigestAddCounter(stateCounter++);
 1890      DigestUpdate(state);
 1891      DigestUpdate(seed);
 1892      DigestDoFinal(state);
 93
 1894      if ((stateCounter % CYCLE_COUNT) == 0)
 095      {
 096        CycleSeed();
 097      }
 1898    }
 99
 100    private void DigestAddCounter(long seedVal)
 28101    {
 28102            byte[] bytes = new byte[8];
 28103            Pack.UInt64_To_LE((ulong)seedVal, bytes);
 28104            digest.BlockUpdate(bytes, 0, bytes.Length);
 28105    }
 106
 107        private void DigestUpdate(byte[] inSeed)
 66108    {
 66109      digest.BlockUpdate(inSeed, 0, inSeed.Length);
 66110    }
 111
 112    private void DigestDoFinal(byte[] result)
 38113    {
 38114      digest.DoFinal(result, 0);
 38115    }
 116  }
 117}