Implement WasabiRandom abstract class.
MODIFY
WalletWasabi.Tests/UnitTests/Crypto/RandomTests.cs
WalletWasabi.Tests/UnitTests/Crypto/RandomTests.cs
@@ -33,9 +33,8 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
var pseudoSet = new HashSet<byte[]>();
var secureSet = new HashSet<byte[]>();
var count = 100;
- IWasabiRandom insecureRandom = new InsecureRandom();
- using var secureRandomToDispose = new SecureRandom();
- IWasabiRandom secureRandom = secureRandomToDispose;
+ var insecureRandom = new InsecureRandom();
+ using var secureRandom = new SecureRandom();
for (int i = 0; i < count; i++)
{
pseudoSet.Add(insecureRandom.GetBytes(10));
@@ -48,7 +47,7 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
[Fact]
public void GetBytesArgumentTests()
{
- var randoms = new List<IWasabiRandom>
+ var randoms = new List<WasabiRandom>
{
new SecureRandom(),
new InsecureRandom(),
@@ -68,11 +67,11 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
var r2 = random.GetBytes(2);
Assert.Equal(2, r2.Length);
}
+ }
- if (random is SecureRandom secureRandom)
+ foreach (var random in randoms.Where(x => x is IDisposable))
{
- secureRandom.Dispose();
- }
+ (random as IDisposable).Dispose();
}
}
@@ -87,7 +86,7 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
};
Assert.Single(singleSet);
- var randoms = new List<IWasabiRandom>
+ var randoms = new List<WasabiRandom>
{
new SecureRandom(),
new InsecureRandom()
@@ -104,11 +103,11 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
set.Add(randomScalar);
}
Assert.Equal(count, set.Count);
+ }
- if (random is SecureRandom secureRandom)
+ foreach (var random in randoms.Where(x => x is IDisposable))
{
- secureRandom.Dispose();
- }
+ (random as IDisposable).Dispose();
}
}
@@ -116,7 +115,6 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
public void ScalarInternalTests()
{
var mockRandom = new MockRandom();
- IWasabiRandom iWasabiRandom = mockRandom;
// The random should not overfow.
mockRandom.GetBytesResults.Add(EC.N.ToBytes());
@@ -134,16 +132,26 @@ namespace WalletWasabi.Tests.UnitTests.Crypto
var biggest = EC.N + one.Negate();
mockRandom.GetBytesResults.Add(biggest.ToBytes());
- var randomScalar = iWasabiRandom.GetScalar();
+ var randomScalar = mockRandom.GetScalar();
Assert.Equal(Scalar.Zero, randomScalar);
- randomScalar = iWasabiRandom.GetScalar();
+ randomScalar = mockRandom.GetScalar();
Assert.Equal(one, randomScalar);
- randomScalar = iWasabiRandom.GetScalar();
+ randomScalar = mockRandom.GetScalar();
Assert.Equal(two, randomScalar);
- randomScalar = iWasabiRandom.GetScalar();
+ randomScalar = mockRandom.GetScalar();
Assert.Equal(big, randomScalar);
- randomScalar = iWasabiRandom.GetScalar();
+ randomScalar = mockRandom.GetScalar();
Assert.Equal(biggest, randomScalar);
}
+
+ [Fact]
+ public void RandomStringTests()
+ {
+ var s1 = RandomString.AlphaNumeric(21, true);
+ Assert.Equal(21, s1.Length);
+
+ var s2 = RandomString.CapitalAlphaNumeric(21, false);
+ Assert.Equal(21, s2.Length);
+ }
}
}

MODIFY
WalletWasabi/Crypto/Randomness/IWasabiRandom.cs
WalletWasabi/Crypto/Randomness/IWasabiRandom.cs
@@ -8,8 +8,12 @@ using WalletWasabi.Helpers;
namespace WalletWasabi.Crypto.Randomness
{
- public interface IWasabiRandom : IRandom
+ public abstract class WasabiRandom : IRandom
{
+ public abstract void GetBytes(byte[] output);
+
+ public abstract void GetBytes(Span<byte> output);
+
public byte[] GetBytes(int length)
{
Guard.MinimumAndNotNull(nameof(length), length, 1);
@@ -18,7 +22,7 @@ namespace WalletWasabi.Crypto.Randomness
return buffer;
}
- public int GetInt(int fromInclusive, int toExclusive);
+ public abstract int GetInt(int fromInclusive, int toExclusive);
public string GetString(int length, string chars)
{

MODIFY
WalletWasabi/Crypto/Randomness/InsecureRandom.cs
WalletWasabi/Crypto/Randomness/InsecureRandom.cs
@@ -4,7 +4,7 @@ using System.Text;
namespace WalletWasabi.Crypto.Randomness
{
- public class InsecureRandom : IWasabiRandom
+ public class InsecureRandom : WasabiRandom
{
public InsecureRandom()
{
@@ -13,10 +13,10 @@ namespace WalletWasabi.Crypto.Randomness
private Random Random { get; }
- public void GetBytes(byte[] buffer) => Random.NextBytes(buffer);
+ public override void GetBytes(byte[] buffer) => Random.NextBytes(buffer);
- public void GetBytes(Span<byte> buffer) => Random.NextBytes(buffer);
+ public override void GetBytes(Span<byte> buffer) => Random.NextBytes(buffer);
- public int GetInt(int fromInclusive, int toExclusive) => Random.Next(fromInclusive, toExclusive);
+ public override int GetInt(int fromInclusive, int toExclusive) => Random.Next(fromInclusive, toExclusive);
}
}

MODIFY
WalletWasabi/Crypto/Randomness/MockRandom.cs
WalletWasabi/Crypto/Randomness/MockRandom.cs
@@ -6,25 +6,25 @@ using System.Text;
namespace WalletWasabi.Crypto.Randomness
{
- public class MockRandom : IWasabiRandom
+ public class MockRandom : WasabiRandom
{
public List<byte[]> GetBytesResults { get; } = new List<byte[]>();
- public void GetBytes(byte[] output)
+ public override void GetBytes(byte[] output)
{
var first = GetBytesResults.First();
GetBytesResults.RemoveFirst();
Buffer.BlockCopy(first, 0, output, 0, first.Length);
}
- public void GetBytes(Span<byte> output)
+ public override void GetBytes(Span<byte> output)
{
var first = GetBytesResults.First();
GetBytesResults.RemoveFirst();
first.AsSpan().CopyTo(output);
}
- public int GetInt(int fromInclusive, int toExclusive)
+ public override int GetInt(int fromInclusive, int toExclusive)
{
throw new NotImplementedException();
}

MODIFY
WalletWasabi/Crypto/Randomness/RandomString.cs
WalletWasabi/Crypto/Randomness/RandomString.cs
@@ -9,18 +9,24 @@ namespace WalletWasabi.Crypto.Randomness
{
public static string FromCharacters(int length, string characters, bool secureRandom = false)
{
- IWasabiRandom random;
+ WasabiRandom random;
if (secureRandom)
{
- using var rand = new SecureRandom();
- random = rand;
+ random = new SecureRandom();
}
else
{
random = new InsecureRandom();
}
- return random.GetString(length, characters);
+ var res = random.GetString(length, characters);
+
+ if (random is IDisposable disposableRandom)
+ {
+ disposableRandom.Dispose();
+ }
+
+ return res;
}
public static string AlphaNumeric(int length, bool secureRandom = false) => FromCharacters(length, Constants.AlphaNumericCharacters, secureRandom);

MODIFY
WalletWasabi/Crypto/Randomness/SecureRandom.cs
WalletWasabi/Crypto/Randomness/SecureRandom.cs
@@ -5,7 +5,7 @@ using System.Text;
namespace WalletWasabi.Crypto.Randomness
{
- public class SecureRandom : IWasabiRandom, IDisposable
+ public class SecureRandom : WasabiRandom, IDisposable
{
private bool _disposedValue;
@@ -16,11 +16,11 @@ namespace WalletWasabi.Crypto.Randomness
private RandomNumberGenerator Random { get; }
- public void GetBytes(byte[] buffer) => Random.GetBytes(buffer);
+ public override void GetBytes(byte[] buffer) => Random.GetBytes(buffer);
- public void GetBytes(Span<byte> buffer) => Random.GetBytes(buffer);
+ public override void GetBytes(Span<byte> buffer) => Random.GetBytes(buffer);
- public int GetInt(int fromInclusive, int toExclusive) => RandomNumberGenerator.GetInt32(fromInclusive, toExclusive);
+ public override int GetInt(int fromInclusive, int toExclusive) => RandomNumberGenerator.GetInt32(fromInclusive, toExclusive);
protected virtual void Dispose(bool disposing)
{

MODIFY
WalletWasabi/Crypto/StringCipher.cs
WalletWasabi/Crypto/StringCipher.cs
@@ -122,7 +122,7 @@ namespace WalletWasabi.Crypto
private static byte[] Generate128BitsOfRandomEntropy()
{
using var secureRandom = new SecureRandom();
- var randomBytes = (secureRandom as IWasabiRandom).GetBytes(16); // 16 Bytes will give us 128 bits.
+ var randomBytes = secureRandom.GetBytes(16); // 16 Bytes will give us 128 bits.
return randomBytes;
}
}

Implement WasabiRandom abstract class.