forked from LinusU/react-native-get-random-values
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
105 lines (84 loc) · 2.96 KB
/
index.js
File metadata and controls
105 lines (84 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
const base64Decode = require('fast-base64-decode')
const { TurboModuleRegistry } = require('react-native')
if (typeof Buffer === 'undefined') {
global.Buffer = require('buffer').Buffer
}
class TypeMismatchError extends Error {}
class QuotaExceededError extends Error {}
let warned = false
function insecureRandomValues (array) {
if (!warned) {
console.warn('Using an insecure random number generator, this should only happen when running in a debugger without support for crypto.getRandomValues')
warned = true
}
for (let i = 0, r; i < array.length; i++) {
if ((i & 0x03) === 0) r = Math.random() * 0x100000000
array[i] = (r >>> ((i & 0x03) << 3)) & 0xff
}
return array
}
let module = null
/**
* @param {number} byteLength
* @returns {string}
*/
function getRandomBase64 (byteLength) {
if (module == null) {
module = TurboModuleRegistry.getEnforcing('RNGetRandomValues')
}
return module.getRandomBase64(byteLength)
}
/**
* @param {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Uint8ClampedArray} array
*/
export function getRandomValues (array) {
if (!(array instanceof Int8Array || array instanceof Uint8Array || array instanceof Int16Array || array instanceof Uint16Array || array instanceof Int32Array || array instanceof Uint32Array || array instanceof Uint8ClampedArray)) {
throw new TypeMismatchError('Expected an integer array')
}
if (array.byteLength > 65536) {
throw new QuotaExceededError('Can only request a maximum of 65536 bytes')
}
// Expo SDK 48+
if (global.expo?.modules?.ExpoCrypto?.getRandomValues) {
// ExpoCrypto.getRandomValues doesn't return the array
global.expo.modules.ExpoCrypto.getRandomValues(array)
return array
}
// Calling getRandomBase64 in remote debugging mode leads to the error
// "Calling synchronous methods on native modules is not supported in Chrome".
// So in that specific case we fall back to just using Math.random().
if (isRemoteDebuggingInChrome()) {
return insecureRandomValues(array)
}
base64Decode(getRandomBase64(array.byteLength), new Uint8Array(array.buffer, array.byteOffset, array.byteLength))
return array
}
function isRemoteDebuggingInChrome () {
// Remote debugging in Chrome is not supported in bridgeless
if ('RN$Bridgeless' in global && RN$Bridgeless === true) {
return false
}
return __DEV__ && typeof global.nativeCallSyncHook === 'undefined'
}
export function seedSJCL (cb) {
// Not going to use sjcl for generation
}
function toBuffer (nativeStr) {
return Buffer.from(nativeStr, 'base64')
}
export function randomBytes (length, cb) {
if (!cb) {
if (length > 65536) {
throw new QuotaExceededError('Can only request a maximum of 65536 bytes')
}
return toBuffer(getRandomBase64(length))
}
try {
if (length > 65536) {
throw new QuotaExceededError('Can only request a maximum of 65536 bytes')
}
cb(null, toBuffer(getRandomBase64(length)))
} catch (err) {
cb(err)
}
}