mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 19:40:29 +00:00
[dart2wasm] Implement _SecureRandom._getBytes
This only changes `_SecureRandom._getBytes` to make the rest of the code work. Implementation is currently slow: for each random number generation, it allocates one JS `Uint8Array`, and because we can't directly read from a JS `Uint8Array` using `dart:js_interop`, a Dart `Uint8List` wrapper for it. We can optimize separately. Fixes #55031. Fixes test lib/math/random_secure_test on browsers. The test keeps failing in d8 as d8 doesn't define the `crypto` object. Change-Id: I9d6bbd1bb576c0d0b7206cb2939ee65d987ec297 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/356040 Commit-Queue: Ömer Ağacan <omersa@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
ff0f5c4bdb
commit
12859761b9
|
@ -2,9 +2,9 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:_internal" show mix64, patch;
|
||||
|
||||
import "dart:typed_data" show Uint32List;
|
||||
import "dart:_internal" show mix64, patch, unsafeCast;
|
||||
import "dart:_js_types" show JSUint8ArrayImpl;
|
||||
import "dart:js_interop";
|
||||
|
||||
/// There are no parts of this patch library.
|
||||
|
||||
|
@ -236,19 +236,53 @@ class _Random implements Random {
|
|||
}
|
||||
}
|
||||
|
||||
@JS('crypto')
|
||||
external _JSCrypto get _jsCryptoGetter;
|
||||
|
||||
final _JSCrypto _jsCrypto = _jsCryptoGetter;
|
||||
|
||||
extension type _JSCrypto._(JSObject _jsCrypto) implements JSObject {}
|
||||
|
||||
extension _JSCryptoGetRandomValues on _JSCrypto {
|
||||
@JS('getRandomValues')
|
||||
external void getRandomValues(JSUint8Array array);
|
||||
}
|
||||
|
||||
@JS('Uint8Array')
|
||||
extension type _JSUint8Array(JSObject _) {
|
||||
external factory _JSUint8Array.create(int length);
|
||||
}
|
||||
|
||||
class _SecureRandom implements Random {
|
||||
final JSUint8ArrayImpl _buffer = unsafeCast<JSUint8ArrayImpl>(
|
||||
(_JSUint8Array.create(8) as JSUint8Array).toDart);
|
||||
|
||||
_SecureRandom() {
|
||||
// Throw early in constructor if entropy source is not hooked up.
|
||||
_getBytes(1);
|
||||
}
|
||||
|
||||
// Return count bytes of entropy as a positive integer; count <= 8.
|
||||
external static int _getBytes(int count);
|
||||
// Return count bytes of entropy as an integer; count <= 8.
|
||||
int _getBytes(int count) {
|
||||
final JSUint8ArrayImpl bufferView =
|
||||
JSUint8ArrayImpl.view(_buffer.buffer, 0, count);
|
||||
|
||||
final JSUint8Array bufferViewJS = bufferView.toJS;
|
||||
_jsCrypto.getRandomValues(bufferViewJS);
|
||||
|
||||
int value = 0;
|
||||
for (int i = 0; i < count; i += 1) {
|
||||
value = (value << 8) | bufferView[i];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int nextInt(int max) {
|
||||
RangeError.checkValueInInterval(
|
||||
max, 1, _POW2_32, "max", "Must be positive and <= 2^32");
|
||||
final byteCount = ((max - 1).bitLength + 7) >> 3;
|
||||
final byteCount =
|
||||
((max - 1).bitLength + 7) >> 3; // Divide number of bits by 8, round up.
|
||||
if (byteCount == 0) {
|
||||
return 0; // Not random if max == 1.
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue