Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/libraries/Native/Unix/System.Native/pal_random.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,23 @@

var DotNetEntropyLib = {
$DOTNETENTROPY: {
// batchedQuotaMax is the max number of bytes as specified by the api spec.
// If the byteLength of array is greater than 65536, throw a QuotaExceededError and terminate the algorithm.
// https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
batchedQuotaMax: 65536,
getBatchedRandomValues: function (buffer, bufferLength) {
// for modern web browsers
// map the work array to the memory buffer passed with the length
for (var i = 0; i < bufferLength; i += this.batchedQuotaMax) {
var view = new Uint8Array(Module.HEAPU8.buffer, buffer + i, Math.min(bufferLength - i, this.batchedQuotaMax));
crypto.getRandomValues(view)
}
}
},
dotnet_browser_entropy : function (buffer, bufferLength) {
// check that we have crypto available
if (typeof crypto === 'object' && typeof crypto['getRandomValues'] === 'function') {
// for modern web browsers
// map the work array to the memory buffer passed with the length
var wrkArray = new Uint8Array(Module.HEAPU8.buffer, buffer, bufferLength);
crypto.getRandomValues(wrkArray);
DOTNETENTROPY.getBatchedRandomValues(buffer, bufferLength)
return 0;
} else {
// we couldn't find a proper implementation, as Math.random() is not suitable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ namespace System.Security.Cryptography.RNG.Tests
{
public class RandomNumberGeneratorTests
{
[Fact]
public static void RandomDistribution()
[Theory]
[InlineData(2048)]
[InlineData(65536)]
[InlineData(1048576)]
public static void RandomDistribution(int arraySize)
{
byte[] random = new byte[2048];
byte[] random = new byte[arraySize];

using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
Expand Down Expand Up @@ -99,26 +102,33 @@ public static void ConcurrentAccess()
}
}

[Fact]
public static void GetNonZeroBytes_Array()
[Theory]
[InlineData(10)]
[InlineData(256)]
[InlineData(65536)]
[InlineData(1048576)]
public static void GetNonZeroBytes_Array(int arraySize)
{
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
AssertExtensions.Throws<ArgumentNullException>("data", () => rng.GetNonZeroBytes(null));

// Array should not have any zeros
byte[] rand = new byte[65536];
byte[] rand = new byte[arraySize];
rng.GetNonZeroBytes(rand);
Assert.Equal(-1, Array.IndexOf<byte>(rand, 0));
}
}

[Fact]
public static void GetBytes_Offset()
[Theory]
[InlineData(400)]
[InlineData(65536)]
[InlineData(1048576)]
public static void GetBytes_Offset(int arraySize)
{
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
byte[] rand = new byte[400];
byte[] rand = new byte[arraySize];

// Set canary bytes
rand[99] = 77;
Expand Down Expand Up @@ -160,6 +170,7 @@ public static void GetBytes_Array_Offset_ZeroCount()
[InlineData(10)]
[InlineData(256)]
[InlineData(65536)]
[InlineData(1048576)]
public static void DifferentSequential_Array(int arraySize)
{
// Ensure that the RNG doesn't produce a stable set of data.
Expand All @@ -186,6 +197,7 @@ public static void DifferentSequential_Array(int arraySize)
[InlineData(10)]
[InlineData(256)]
[InlineData(65536)]
[InlineData(1048576)]
public static void DifferentParallel(int arraySize)
{
// Ensure that two RNGs don't produce the same data series (such as being implemented via new Random(1)).
Expand Down Expand Up @@ -243,25 +255,32 @@ public static void GetBytes_Int_Empty()
Assert.Empty(result);
}

[Fact]
public static void GetBytes_Int_RandomDistribution()
[Theory]
[InlineData(2048)]
[InlineData(65536)]
[InlineData(1048576)]
public static void GetBytes_Int_RandomDistribution(int arraySize)
{
byte[] result = RandomNumberGenerator.GetBytes(2048);
byte[] result = RandomNumberGenerator.GetBytes(arraySize);
RandomDataGenerator.VerifyRandomDistribution(result);
}

[Fact]
public static void GetBytes_Int_NotSame()
[Theory]
[InlineData(2048)]
[InlineData(65536)]
[InlineData(1048576)]
public static void GetBytes_Int_NotSame(int arraySize)
{
byte[] result1 = RandomNumberGenerator.GetBytes(2048);
byte[] result2 = RandomNumberGenerator.GetBytes(2048);
byte[] result1 = RandomNumberGenerator.GetBytes(arraySize);
byte[] result2 = RandomNumberGenerator.GetBytes(arraySize);
Assert.NotEqual(result1, result2);
}

[Theory]
[InlineData(10)]
[InlineData(256)]
[InlineData(65536)]
[InlineData(1048576)]
public static void DifferentSequential_Span(int arraySize)
{
// Ensure that the RNG doesn't produce a stable set of data.
Expand Down Expand Up @@ -295,12 +314,16 @@ public static void GetBytes_Span_ZeroCount()
}
}

[Fact]
public static void GetNonZeroBytes_Span()
[Theory]
[InlineData(10)]
[InlineData(256)]
[InlineData(65536)]
[InlineData(1048576)]
public static void GetNonZeroBytes_Span(int arraySize)
{
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
var rand = new byte[65536];
var rand = new byte[arraySize];
rng.GetNonZeroBytes(new Span<byte>(rand));
Assert.Equal(-1, Array.IndexOf<byte>(rand, 0));
}
Expand Down