@1fun-games/rng 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/dist/hmac-drbg/hmac-drbg.d.ts +28 -0
- package/dist/hmac-drbg/hmac-drbg.js +149 -0
- package/dist/hmac-drbg/hmac-drbg.js.map +1 -0
- package/dist/hmac-drbg/index.d.ts +1 -0
- package/dist/hmac-drbg/index.js +6 -0
- package/dist/hmac-drbg/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/rng/draw-with-replacement.d.ts +13 -0
- package/dist/rng/draw-with-replacement.js +23 -0
- package/dist/rng/draw-with-replacement.js.map +1 -0
- package/dist/rng/draw-without-replacement.d.ts +13 -0
- package/dist/rng/draw-without-replacement.js +28 -0
- package/dist/rng/draw-without-replacement.js.map +1 -0
- package/dist/rng/generate-random-draws.d.ts +20 -0
- package/dist/rng/generate-random-draws.js +34 -0
- package/dist/rng/generate-random-draws.js.map +1 -0
- package/dist/rng/generate-uniform-uint-32.d.ts +12 -0
- package/dist/rng/generate-uniform-uint-32.js +34 -0
- package/dist/rng/generate-uniform-uint-32.js.map +1 -0
- package/dist/rng/index.d.ts +4 -0
- package/dist/rng/index.js +12 -0
- package/dist/rng/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils/create-entropy-input.d.ts +10 -0
- package/dist/utils/create-entropy-input.js +19 -0
- package/dist/utils/create-entropy-input.js.map +1 -0
- package/dist/utils/generate-server-seed.d.ts +6 -0
- package/dist/utils/generate-server-seed.js +13 -0
- package/dist/utils/generate-server-seed.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 1fun provider ltd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# GLI-19 Compliant Cryptographically Secure Pseudo Random Number Generator (RNG)
|
|
2
|
+
|
|
3
|
+
This repository implements a cryptographically secure Random Number Generator (RNG) built on **HMAC-DRBG** (Deterministic Random Bit Generator).
|
|
4
|
+
|
|
5
|
+
The project follows the technical requirements from [GLI-19 Chapter 3: Random Number Generator (RNG) Requirements](https://gaminglabs.com/gli-standards/).
|
|
6
|
+
|
|
7
|
+
This implementation is designed as production-ready RNG code and can be submitted for **GLI / iTech Labs certification**.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Structure
|
|
11
|
+
- `cli` - CLI tools for generating test data
|
|
12
|
+
- `examples` - Example usage of the RNG
|
|
13
|
+
- `src/hmac-drbg` - HMAC-DRBG implementation
|
|
14
|
+
- `src/rng` - Shuffling, scaling and draw utilities
|
|
15
|
+
- `src/utils` - Some helpful utilities
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## Dieharder Docker
|
|
19
|
+
This project includes a Dockerfile with [dieharder](https://webhome.phy.duke.edu/~rgb/General/dieharder.php).
|
|
20
|
+
|
|
21
|
+
```shell
|
|
22
|
+
docker build -t 1fun-rng .
|
|
23
|
+
docker run -it --rm 1fun-rng
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> ⚠️ **Note on Dieharder Testing**
|
|
27
|
+
> Some statistical tests in the Dieharder suite are very data-hungry.
|
|
28
|
+
> To achieve a full **"PASSED"** status across all tests, a **large amount of RNG output data** may be required.
|
|
29
|
+
> This is expected behavior since certain tests need millions or even billions of samples to converge reliably.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## Generate output to txt file for usage with dieharder
|
|
33
|
+
|
|
34
|
+
```shell
|
|
35
|
+
npx ts-node ./cli/generate-dieharder-ascii.ts \
|
|
36
|
+
--client-seed abcdefghijklmnopqrstuvwxyz \
|
|
37
|
+
--count 100000000 \
|
|
38
|
+
--destination hmac-dbrng.txt
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This creates a file `hmac-dbrng.txt` with 100_000_000 values generated with the HMAC-DRBG algorithm.
|
|
42
|
+
|
|
43
|
+
It can be used with the [dieharder](https://webhome.phy.duke.edu/~rgb/General/dieharder.php) test suite:
|
|
44
|
+
```shell
|
|
45
|
+
dieharder -g 202 -f hmac-dbrng.txt -a
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Generate output to txt file for GLI
|
|
50
|
+
|
|
51
|
+
```shell
|
|
52
|
+
npx ts-node ./cli/generate-gli-output.ts \
|
|
53
|
+
--client-seed abcdefghijklmnopqrstuvwxyz \
|
|
54
|
+
--range-start 1 \
|
|
55
|
+
--range-end 52 \
|
|
56
|
+
--selections 52 \
|
|
57
|
+
--draws 100000 \
|
|
58
|
+
--destination gli.txt
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The additional parameter `--with-replacements` allows for numbers to be repeated within selections.
|
|
62
|
+
|
|
63
|
+
> range-start and range-end are inclusive
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Acknowledgements
|
|
67
|
+
This project draws ideas and inspiration (and in some cases code concepts) from the following open-source projects:
|
|
68
|
+
|
|
69
|
+
- [Mintablo/mintablo-rng](https://github.com/Mintablo/mintablo-rng)
|
|
70
|
+
- [bcoin-org/bcrypto](https://github.com/bcoin-org/bcrypto)
|
|
71
|
+
- [indutny/hmac-drbg](https://github.com/indutny/hmac-drbg)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript HMAC-DRBG implementation.
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025, 1fun provider ltd
|
|
5
|
+
*
|
|
6
|
+
* Based on code from:
|
|
7
|
+
* - bcrypto (Christopher Jeffrey, MIT License)
|
|
8
|
+
* https://github.com/bcoin-org/bcrypto/blob/master/lib/js/hmac-drbg.js
|
|
9
|
+
* - hmac-drbg (Fedor Indutny, MIT License)
|
|
10
|
+
* https://github.com/indutny/hmac-drbg
|
|
11
|
+
*/
|
|
12
|
+
export type HashAlgorithm = 'sha1' | 'sha224' | 'sha256' | 'sha384' | 'sha512' | 'sha3-224' | 'sha3-256' | 'sha3-384' | 'sha3-512';
|
|
13
|
+
export declare class HmacDrbg {
|
|
14
|
+
private readonly algorithm;
|
|
15
|
+
private k;
|
|
16
|
+
private v;
|
|
17
|
+
private readonly hashLen;
|
|
18
|
+
private readonly minEntropy;
|
|
19
|
+
private rounds;
|
|
20
|
+
constructor(algorithm?: HashAlgorithm, entropy?: Buffer, nonce?: Buffer, personalization?: Buffer);
|
|
21
|
+
private hmac;
|
|
22
|
+
private update;
|
|
23
|
+
instantiate(entropy: Buffer, nonce?: Buffer, personalization?: Buffer): void;
|
|
24
|
+
reseed(entropy: Buffer, additionalInput?: Buffer): void;
|
|
25
|
+
generate(bytesRequested: number, additionalInput?: Buffer): Buffer;
|
|
26
|
+
randomBytes(length: number): Buffer;
|
|
27
|
+
randomInt(min: number, max: number): number;
|
|
28
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TypeScript HMAC-DRBG implementation.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2025, 1fun provider ltd
|
|
6
|
+
*
|
|
7
|
+
* Based on code from:
|
|
8
|
+
* - bcrypto (Christopher Jeffrey, MIT License)
|
|
9
|
+
* https://github.com/bcoin-org/bcrypto/blob/master/lib/js/hmac-drbg.js
|
|
10
|
+
* - hmac-drbg (Fedor Indutny, MIT License)
|
|
11
|
+
* https://github.com/indutny/hmac-drbg
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.HmacDrbg = void 0;
|
|
15
|
+
const node_crypto_1 = require("node:crypto");
|
|
16
|
+
/*
|
|
17
|
+
* Constants
|
|
18
|
+
*/
|
|
19
|
+
const RESEED_INTERVAL = 0x1000000000000;
|
|
20
|
+
const HASH_LENGTHS = {
|
|
21
|
+
sha1: 20,
|
|
22
|
+
sha224: 28,
|
|
23
|
+
sha256: 32,
|
|
24
|
+
sha384: 48,
|
|
25
|
+
sha512: 64,
|
|
26
|
+
'sha3-224': 28,
|
|
27
|
+
'sha3-256': 32,
|
|
28
|
+
'sha3-384': 48,
|
|
29
|
+
'sha3-512': 64,
|
|
30
|
+
};
|
|
31
|
+
const MIN_ENTROPY = {
|
|
32
|
+
sha1: 10,
|
|
33
|
+
sha224: 14,
|
|
34
|
+
sha256: 16,
|
|
35
|
+
sha384: 24,
|
|
36
|
+
sha512: 32,
|
|
37
|
+
'sha3-224': 14,
|
|
38
|
+
'sha3-256': 16,
|
|
39
|
+
'sha3-384': 24,
|
|
40
|
+
'sha3-512': 32,
|
|
41
|
+
};
|
|
42
|
+
class HmacDrbg {
|
|
43
|
+
algorithm;
|
|
44
|
+
k;
|
|
45
|
+
v;
|
|
46
|
+
hashLen;
|
|
47
|
+
minEntropy;
|
|
48
|
+
rounds = 0;
|
|
49
|
+
constructor(algorithm = 'sha256', entropy, nonce, personalization) {
|
|
50
|
+
this.algorithm = algorithm;
|
|
51
|
+
this.hashLen = HASH_LENGTHS[algorithm];
|
|
52
|
+
this.minEntropy = MIN_ENTROPY[algorithm];
|
|
53
|
+
this.k = Buffer.alloc(this.hashLen, 0x00);
|
|
54
|
+
this.v = Buffer.alloc(this.hashLen, 0x01);
|
|
55
|
+
if (entropy) {
|
|
56
|
+
this.instantiate(entropy, nonce, personalization);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
hmac(key, data) {
|
|
60
|
+
return (0, node_crypto_1.createHmac)(this.algorithm, key).update(data).digest();
|
|
61
|
+
}
|
|
62
|
+
update(providedData) {
|
|
63
|
+
const data = providedData || Buffer.alloc(0);
|
|
64
|
+
// K = HMAC(K, V || 0x00 || provided_data)
|
|
65
|
+
this.k = this.hmac(this.k, Buffer.concat([this.v, Buffer.from([0x00]), data]));
|
|
66
|
+
// V = HMAC(K, V)
|
|
67
|
+
this.v = this.hmac(this.k, this.v);
|
|
68
|
+
if (data.length > 0) {
|
|
69
|
+
// K = HMAC(K, V || 0x01 || provided_data)
|
|
70
|
+
this.k = this.hmac(this.k, Buffer.concat([this.v, Buffer.from([0x01]), data]));
|
|
71
|
+
// V = HMAC(K, V)
|
|
72
|
+
this.v = this.hmac(this.k, this.v);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
instantiate(entropy, nonce, personalization) {
|
|
76
|
+
if (!Buffer.isBuffer(entropy)) {
|
|
77
|
+
throw new TypeError('Entropy must be a Buffer');
|
|
78
|
+
}
|
|
79
|
+
const seedMaterial = Buffer.concat([
|
|
80
|
+
entropy,
|
|
81
|
+
nonce || Buffer.alloc(0),
|
|
82
|
+
personalization || Buffer.alloc(0),
|
|
83
|
+
]);
|
|
84
|
+
if (seedMaterial.length < this.minEntropy) {
|
|
85
|
+
throw new Error('Not enough entropy.');
|
|
86
|
+
}
|
|
87
|
+
// Reset state
|
|
88
|
+
this.k.fill(0x00);
|
|
89
|
+
this.v.fill(0x01);
|
|
90
|
+
this.update(seedMaterial);
|
|
91
|
+
this.rounds = 1;
|
|
92
|
+
}
|
|
93
|
+
reseed(entropy, additionalInput) {
|
|
94
|
+
if (!Buffer.isBuffer(entropy)) {
|
|
95
|
+
throw new TypeError('Entropy must be a Buffer');
|
|
96
|
+
}
|
|
97
|
+
if (this.rounds === 0) {
|
|
98
|
+
throw new Error('DRBG not initialized.');
|
|
99
|
+
}
|
|
100
|
+
const seedMaterial = Buffer.concat([entropy, additionalInput || Buffer.alloc(0)]);
|
|
101
|
+
if (seedMaterial.length < this.minEntropy) {
|
|
102
|
+
throw new Error('Not enough entropy.');
|
|
103
|
+
}
|
|
104
|
+
this.update(seedMaterial);
|
|
105
|
+
this.rounds = 1;
|
|
106
|
+
}
|
|
107
|
+
generate(bytesRequested, additionalInput) {
|
|
108
|
+
if (this.rounds === 0) {
|
|
109
|
+
throw new Error('DRBG not initialized.');
|
|
110
|
+
}
|
|
111
|
+
if (this.rounds > RESEED_INTERVAL) {
|
|
112
|
+
throw new Error('Reseed is required.');
|
|
113
|
+
}
|
|
114
|
+
if (additionalInput?.length) {
|
|
115
|
+
this.update(additionalInput);
|
|
116
|
+
}
|
|
117
|
+
const result = Buffer.alloc(bytesRequested);
|
|
118
|
+
let offset = 0;
|
|
119
|
+
while (offset < bytesRequested) {
|
|
120
|
+
this.v = this.hmac(this.k, this.v);
|
|
121
|
+
const copyLen = Math.min(this.hashLen, bytesRequested - offset);
|
|
122
|
+
this.v.copy(result, offset, 0, copyLen);
|
|
123
|
+
offset += copyLen;
|
|
124
|
+
}
|
|
125
|
+
this.update(additionalInput);
|
|
126
|
+
this.rounds += 1;
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
// Convenience methods
|
|
130
|
+
randomBytes(length) {
|
|
131
|
+
return this.generate(length);
|
|
132
|
+
}
|
|
133
|
+
randomInt(min, max) {
|
|
134
|
+
const range = max - min;
|
|
135
|
+
// Handle edge case where the range is 0 or 1
|
|
136
|
+
if (range <= 1) {
|
|
137
|
+
return min;
|
|
138
|
+
}
|
|
139
|
+
const bytes = Math.max(1, Math.ceil(Math.log2(range) / 8));
|
|
140
|
+
let value;
|
|
141
|
+
do {
|
|
142
|
+
const buf = this.generate(bytes);
|
|
143
|
+
value = buf.readUIntBE(0, bytes);
|
|
144
|
+
} while (value >= range);
|
|
145
|
+
return min + value;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.HmacDrbg = HmacDrbg;
|
|
149
|
+
//# sourceMappingURL=hmac-drbg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmac-drbg.js","sourceRoot":"","sources":["../../src/hmac-drbg/hmac-drbg.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { HmacDrbg } from './hmac-drbg';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HmacDrbg = void 0;
|
|
4
|
+
var hmac_drbg_1 = require("./hmac-drbg");
|
|
5
|
+
Object.defineProperty(exports, "HmacDrbg", { enumerable: true, get: function () { return hmac_drbg_1.HmacDrbg; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hmac-drbg/index.ts"],"names":[],"mappings":";;;AAAA,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateServerSeed = exports.createEntropyInput = exports.drawWithoutReplacement = exports.drawWithReplacement = exports.generateUniformUint32 = exports.generateRandomDraws = exports.HmacDrbg = void 0;
|
|
4
|
+
var hmac_drbg_1 = require("./hmac-drbg");
|
|
5
|
+
Object.defineProperty(exports, "HmacDrbg", { enumerable: true, get: function () { return hmac_drbg_1.HmacDrbg; } });
|
|
6
|
+
var rng_1 = require("./rng");
|
|
7
|
+
Object.defineProperty(exports, "generateRandomDraws", { enumerable: true, get: function () { return rng_1.generateRandomDraws; } });
|
|
8
|
+
Object.defineProperty(exports, "generateUniformUint32", { enumerable: true, get: function () { return rng_1.generateUniformUint32; } });
|
|
9
|
+
Object.defineProperty(exports, "drawWithReplacement", { enumerable: true, get: function () { return rng_1.drawWithReplacement; } });
|
|
10
|
+
Object.defineProperty(exports, "drawWithoutReplacement", { enumerable: true, get: function () { return rng_1.drawWithoutReplacement; } });
|
|
11
|
+
var utils_1 = require("./utils");
|
|
12
|
+
Object.defineProperty(exports, "createEntropyInput", { enumerable: true, get: function () { return utils_1.createEntropyInput; } });
|
|
13
|
+
Object.defineProperty(exports, "generateServerSeed", { enumerable: true, get: function () { return utils_1.generateServerSeed; } });
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA;AAEjB,6BAKe;AAJb,0GAAA,mBAAmB,OAAA;AACnB,4GAAA,qBAAqB,OAAA;AACrB,0GAAA,mBAAmB,OAAA;AACnB,6GAAA,sBAAsB,OAAA;AAGxB,iCAAiE;AAAxD,2GAAA,kBAAkB,OAAA;AAAE,2GAAA,kBAAkB,OAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HmacDrbg } from '../hmac-drbg';
|
|
2
|
+
/**
|
|
3
|
+
* Draws a sequence of random integers from the inclusive range [min, max],
|
|
4
|
+
* allowing repeated values.
|
|
5
|
+
*
|
|
6
|
+
* @param {HmacDrbg} drbg - Cryptographically secure generator (HMAC-DRBG).
|
|
7
|
+
* @param {number} min - Lower bound, inclusive.
|
|
8
|
+
* @param {number} max - Upper bound, inclusive.
|
|
9
|
+
* @param {number} selection - How many values to pick.
|
|
10
|
+
* @returns {number[]} An array of random integers of length `selections`,
|
|
11
|
+
* where values may repeat.
|
|
12
|
+
*/
|
|
13
|
+
export declare function drawWithReplacement(drbg: HmacDrbg, min: number, max: number, selection: number): number[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.drawWithReplacement = drawWithReplacement;
|
|
4
|
+
const generate_uniform_uint_32_1 = require("./generate-uniform-uint-32");
|
|
5
|
+
/**
|
|
6
|
+
* Draws a sequence of random integers from the inclusive range [min, max],
|
|
7
|
+
* allowing repeated values.
|
|
8
|
+
*
|
|
9
|
+
* @param {HmacDrbg} drbg - Cryptographically secure generator (HMAC-DRBG).
|
|
10
|
+
* @param {number} min - Lower bound, inclusive.
|
|
11
|
+
* @param {number} max - Upper bound, inclusive.
|
|
12
|
+
* @param {number} selection - How many values to pick.
|
|
13
|
+
* @returns {number[]} An array of random integers of length `selections`,
|
|
14
|
+
* where values may repeat.
|
|
15
|
+
*/
|
|
16
|
+
function drawWithReplacement(drbg, min, max, selection) {
|
|
17
|
+
const draw = new Array(selection);
|
|
18
|
+
for (let i = 0; i < selection; i++) {
|
|
19
|
+
draw[i] = (0, generate_uniform_uint_32_1.generateUniformUint32)(drbg, min, max);
|
|
20
|
+
}
|
|
21
|
+
return draw;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=draw-with-replacement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw-with-replacement.js","sourceRoot":"","sources":["../../src/rng/draw-with-replacement.ts"],"names":[],"mappings":";;AAeA,kDAaC;AA1BD,yEAAmE;AAEnE;;;;;;;;;;GAUG;AACH,SAAgB,mBAAmB,CACjC,IAAc,EACd,GAAW,EACX,GAAW,EACX,SAAiB;IAEjB,MAAM,IAAI,GAAG,IAAI,KAAK,CAAS,SAAS,CAAC,CAAC;IAE1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAA,gDAAqB,EAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HmacDrbg } from '../hmac-drbg';
|
|
2
|
+
/**
|
|
3
|
+
* Picks `selection` unique integers from the inclusive range [min, max]
|
|
4
|
+
* using a partial Fisher–Yates shuffle (unbiased). Returns them in random order.
|
|
5
|
+
*
|
|
6
|
+
* @param {HmacDrbg} drbg - Cryptographically secure generator (HMAC-DRBG).
|
|
7
|
+
* @param {number} min - Lower bound, inclusive.
|
|
8
|
+
* @param {number} max - Upper bound, inclusive.
|
|
9
|
+
* @param {number} selection - How many values to pick.
|
|
10
|
+
* @returns {number[]} Array of `selection` distinct integers from the range.
|
|
11
|
+
* @throws {RangeError} If `selection` is out of range.
|
|
12
|
+
*/
|
|
13
|
+
export declare function drawWithoutReplacement(drbg: HmacDrbg, min: number, max: number, selection: number): number[];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.drawWithoutReplacement = drawWithoutReplacement;
|
|
4
|
+
const generate_uniform_uint_32_1 = require("./generate-uniform-uint-32");
|
|
5
|
+
/**
|
|
6
|
+
* Picks `selection` unique integers from the inclusive range [min, max]
|
|
7
|
+
* using a partial Fisher–Yates shuffle (unbiased). Returns them in random order.
|
|
8
|
+
*
|
|
9
|
+
* @param {HmacDrbg} drbg - Cryptographically secure generator (HMAC-DRBG).
|
|
10
|
+
* @param {number} min - Lower bound, inclusive.
|
|
11
|
+
* @param {number} max - Upper bound, inclusive.
|
|
12
|
+
* @param {number} selection - How many values to pick.
|
|
13
|
+
* @returns {number[]} Array of `selection` distinct integers from the range.
|
|
14
|
+
* @throws {RangeError} If `selection` is out of range.
|
|
15
|
+
*/
|
|
16
|
+
function drawWithoutReplacement(drbg, min, max, selection) {
|
|
17
|
+
const size = max - min + 1;
|
|
18
|
+
if (selection < 0 || selection > size) {
|
|
19
|
+
throw new RangeError('Range too small for desired selection size');
|
|
20
|
+
}
|
|
21
|
+
const a = Array.from({ length: size }, (_, k) => min + k);
|
|
22
|
+
for (let i = 0; i < selection; i++) {
|
|
23
|
+
const j = i + (0, generate_uniform_uint_32_1.generateUniformUint32)(drbg, 0, size - i - 1);
|
|
24
|
+
[a[i], a[j]] = [a[j], a[i]];
|
|
25
|
+
}
|
|
26
|
+
return a.slice(0, selection);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=draw-without-replacement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw-without-replacement.js","sourceRoot":"","sources":["../../src/rng/draw-without-replacement.ts"],"names":[],"mappings":";;AAeA,wDAmBC;AAhCD,yEAAmE;AAEnE;;;;;;;;;;GAUG;AACH,SAAgB,sBAAsB,CACpC,IAAc,EACd,GAAW,EACX,GAAW,EACX,SAAiB;IAEjB,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IAC3B,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,IAAI,EAAE,CAAC;QACtC,MAAM,IAAI,UAAU,CAAC,4CAA4C,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAA,gDAAqB,EAAC,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { HmacDrbg } from '../hmac-drbg';
|
|
2
|
+
export type RandomDraws = number[][];
|
|
3
|
+
/**
|
|
4
|
+
* Generates multiple random draws of integers within a given inclusive range.
|
|
5
|
+
*
|
|
6
|
+
* Each draw is either sampled with replacement (values can repeat within a draw),
|
|
7
|
+
* or without replacement (values are unique within a draw, using Fisher–Yates shuffle).
|
|
8
|
+
*
|
|
9
|
+
* @param {HmacDrbg} drbg - Cryptographically secure generator (HMAC-DRBG).
|
|
10
|
+
* @param {number} min - Lower bound of the range (inclusive).
|
|
11
|
+
* @param {number} max - Upper bound of the range (inclusive).
|
|
12
|
+
* @param {number} [selections=1] - Number of values to select per draw.
|
|
13
|
+
* @param {number} [draws=1] - Number of independent draws to generate.
|
|
14
|
+
* @param {boolean} [withReplacements=false] - Whether to allow repeated values within a draw.
|
|
15
|
+
* - `true`: Each selection is independent, values may repeat.
|
|
16
|
+
* - `false`: Each selection is unique within a draw (Fisher–Yates sampling).
|
|
17
|
+
* @returns {RandomDraws} A 2D array of shape [draws][selections],
|
|
18
|
+
* where each sub-array contains one draw of random integers.
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateRandomDraws(drbg: HmacDrbg, min: number, max: number, selections?: number, draws?: number, withReplacements?: boolean): RandomDraws;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateRandomDraws = generateRandomDraws;
|
|
4
|
+
const draw_with_replacement_1 = require("./draw-with-replacement");
|
|
5
|
+
const draw_without_replacement_1 = require("./draw-without-replacement");
|
|
6
|
+
/**
|
|
7
|
+
* Generates multiple random draws of integers within a given inclusive range.
|
|
8
|
+
*
|
|
9
|
+
* Each draw is either sampled with replacement (values can repeat within a draw),
|
|
10
|
+
* or without replacement (values are unique within a draw, using Fisher–Yates shuffle).
|
|
11
|
+
*
|
|
12
|
+
* @param {HmacDrbg} drbg - Cryptographically secure generator (HMAC-DRBG).
|
|
13
|
+
* @param {number} min - Lower bound of the range (inclusive).
|
|
14
|
+
* @param {number} max - Upper bound of the range (inclusive).
|
|
15
|
+
* @param {number} [selections=1] - Number of values to select per draw.
|
|
16
|
+
* @param {number} [draws=1] - Number of independent draws to generate.
|
|
17
|
+
* @param {boolean} [withReplacements=false] - Whether to allow repeated values within a draw.
|
|
18
|
+
* - `true`: Each selection is independent, values may repeat.
|
|
19
|
+
* - `false`: Each selection is unique within a draw (Fisher–Yates sampling).
|
|
20
|
+
* @returns {RandomDraws} A 2D array of shape [draws][selections],
|
|
21
|
+
* where each sub-array contains one draw of random integers.
|
|
22
|
+
*/
|
|
23
|
+
function generateRandomDraws(drbg, min, max, selections = 1, draws = 1, withReplacements = false) {
|
|
24
|
+
const result = new Array(draws);
|
|
25
|
+
for (let i = 0; i < draws; i++) {
|
|
26
|
+
if (withReplacements) {
|
|
27
|
+
result[i] = (0, draw_with_replacement_1.drawWithReplacement)(drbg, min, max, selections);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
result[i] = (0, draw_without_replacement_1.drawWithoutReplacement)(drbg, min, max, selections);
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=generate-random-draws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-random-draws.js","sourceRoot":"","sources":["../../src/rng/generate-random-draws.ts"],"names":[],"mappings":";;AAwBA,kDAoBC;AA1CD,mEAA8D;AAC9D,yEAAoE;AAIpE;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,mBAAmB,CACjC,IAAc,EACd,GAAW,EACX,GAAW,EACX,aAAqB,CAAC,EACtB,QAAgB,CAAC,EACjB,mBAA4B,KAAK;IAEjC,MAAM,MAAM,GAAgB,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IAE7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,CAAC,CAAC,CAAC,GAAG,IAAA,2CAAmB,EAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;YAC5D,SAAS;QACX,CAAC;QAED,MAAM,CAAC,CAAC,CAAC,GAAG,IAAA,iDAAsB,EAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { HmacDrbg } from '../hmac-drbg';
|
|
2
|
+
/**
|
|
3
|
+
* Returns a uniformly distributed integer in the inclusive range [min, max]
|
|
4
|
+
* using rejection sampling (no modulo bias).
|
|
5
|
+
*
|
|
6
|
+
* @param {HmacDrbg} drbg - Cryptographically secure generator (HMAC-DRBG).
|
|
7
|
+
* @param {number} [min=0] - Lower bound (0..4294967295), inclusive.
|
|
8
|
+
* @param {number} [max=0xFFFFFFFF] - Upper bound (>= min), inclusive.
|
|
9
|
+
* @returns {number} A random UInt32 in [min, max].
|
|
10
|
+
* @throws {RangeError} If bounds are not safe integers, out of UInt32 range, or min > max.
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateUniformUint32(drbg: HmacDrbg, min?: number, max?: number): number;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateUniformUint32 = generateUniformUint32;
|
|
4
|
+
/**
|
|
5
|
+
* Returns a uniformly distributed integer in the inclusive range [min, max]
|
|
6
|
+
* using rejection sampling (no modulo bias).
|
|
7
|
+
*
|
|
8
|
+
* @param {HmacDrbg} drbg - Cryptographically secure generator (HMAC-DRBG).
|
|
9
|
+
* @param {number} [min=0] - Lower bound (0..4294967295), inclusive.
|
|
10
|
+
* @param {number} [max=0xFFFFFFFF] - Upper bound (>= min), inclusive.
|
|
11
|
+
* @returns {number} A random UInt32 in [min, max].
|
|
12
|
+
* @throws {RangeError} If bounds are not safe integers, out of UInt32 range, or min > max.
|
|
13
|
+
*/
|
|
14
|
+
function generateUniformUint32(drbg, min = 0, max = 0xffffffff) {
|
|
15
|
+
if (!Number.isSafeInteger(min) || !Number.isSafeInteger(max)) {
|
|
16
|
+
throw new RangeError('min/max must be safe integers');
|
|
17
|
+
}
|
|
18
|
+
if (min < 0 || max > 0xffffffff || min > max) {
|
|
19
|
+
throw new RangeError('UInt32 range should be in 0..4294967295 and min <= max');
|
|
20
|
+
}
|
|
21
|
+
const range = max - min + 1;
|
|
22
|
+
if (range === 1) {
|
|
23
|
+
return min;
|
|
24
|
+
}
|
|
25
|
+
const SPACE = 0x1_0000_0000; // 2^32
|
|
26
|
+
const THRESHOLD = SPACE - (SPACE % range);
|
|
27
|
+
while (true) {
|
|
28
|
+
const value = drbg.generate(4).readUInt32LE(0); // 0..2^32-1
|
|
29
|
+
if (value < THRESHOLD) {
|
|
30
|
+
return min + (value % range);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=generate-uniform-uint-32.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-uniform-uint-32.js","sourceRoot":"","sources":["../../src/rng/generate-uniform-uint-32.ts"],"names":[],"mappings":";;AAYA,sDA2BC;AArCD;;;;;;;;;GASG;AACH,SAAgB,qBAAqB,CACnC,IAAc,EACd,MAAc,CAAC,EACf,MAAc,UAAU;IAExB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,UAAU,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QAC7C,MAAM,IAAI,UAAU,CAAC,wDAAwD,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IAC5B,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,OAAO;IACpC,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IAE1C,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC5D,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YACtB,OAAO,GAAG,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateUniformUint32 = exports.generateRandomDraws = exports.drawWithoutReplacement = exports.drawWithReplacement = void 0;
|
|
4
|
+
var draw_with_replacement_1 = require("./draw-with-replacement");
|
|
5
|
+
Object.defineProperty(exports, "drawWithReplacement", { enumerable: true, get: function () { return draw_with_replacement_1.drawWithReplacement; } });
|
|
6
|
+
var draw_without_replacement_1 = require("./draw-without-replacement");
|
|
7
|
+
Object.defineProperty(exports, "drawWithoutReplacement", { enumerable: true, get: function () { return draw_without_replacement_1.drawWithoutReplacement; } });
|
|
8
|
+
var generate_random_draws_1 = require("./generate-random-draws");
|
|
9
|
+
Object.defineProperty(exports, "generateRandomDraws", { enumerable: true, get: function () { return generate_random_draws_1.generateRandomDraws; } });
|
|
10
|
+
var generate_uniform_uint_32_1 = require("./generate-uniform-uint-32");
|
|
11
|
+
Object.defineProperty(exports, "generateUniformUint32", { enumerable: true, get: function () { return generate_uniform_uint_32_1.generateUniformUint32; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":";;;AAAA,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,uEAAoE;AAA3D,kIAAA,sBAAsB,OAAA;AAC/B,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/index.ts","../src/hmac-drbg/hmac-drbg.ts","../src/hmac-drbg/index.ts","../src/rng/draw-with-replacement.ts","../src/rng/draw-without-replacement.ts","../src/rng/generate-random-draws.ts","../src/rng/generate-uniform-uint-32.ts","../src/rng/index.ts","../src/utils/create-entropy-input.ts","../src/utils/generate-server-seed.ts","../src/utils/index.ts"],"version":"5.9.2"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates entropy input as HMAC(serverSeed, `${clientSeed}:${nonce}`).
|
|
3
|
+
*
|
|
4
|
+
* @param {string} serverSeed - HMAC key.
|
|
5
|
+
* @param {string} clientSeed - Client seed.
|
|
6
|
+
* @param {number} nonce - Monotonic nonce.
|
|
7
|
+
* @param {string} [algorithm='sha256'] - Hash algorithm.
|
|
8
|
+
* @returns {Buffer} HMAC digest.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createEntropyInput(serverSeed: string, clientSeed: string, nonce: number, algorithm?: string): Buffer;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createEntropyInput = createEntropyInput;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
/**
|
|
6
|
+
* Creates entropy input as HMAC(serverSeed, `${clientSeed}:${nonce}`).
|
|
7
|
+
*
|
|
8
|
+
* @param {string} serverSeed - HMAC key.
|
|
9
|
+
* @param {string} clientSeed - Client seed.
|
|
10
|
+
* @param {number} nonce - Monotonic nonce.
|
|
11
|
+
* @param {string} [algorithm='sha256'] - Hash algorithm.
|
|
12
|
+
* @returns {Buffer} HMAC digest.
|
|
13
|
+
*/
|
|
14
|
+
function createEntropyInput(serverSeed, clientSeed, nonce, algorithm = 'sha256') {
|
|
15
|
+
const hmac = (0, node_crypto_1.createHmac)(algorithm, serverSeed);
|
|
16
|
+
hmac.update(`${clientSeed}:${nonce}`);
|
|
17
|
+
return hmac.digest();
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=create-entropy-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-entropy-input.js","sourceRoot":"","sources":["../../src/utils/create-entropy-input.ts"],"names":[],"mappings":";;AAWA,gDAWC;AAtBD,6CAAyC;AAEzC;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAChC,UAAkB,EAClB,UAAkB,EAClB,KAAa,EACb,YAAoB,QAAQ;IAE5B,MAAM,IAAI,GAAG,IAAA,wBAAU,EAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAE/C,IAAI,CAAC,MAAM,CAAC,GAAG,UAAU,IAAI,KAAK,EAAE,CAAC,CAAC;IAEtC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateServerSeed = generateServerSeed;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
/**
|
|
6
|
+
* Generates a 32-byte cryptographically secure server seed (hex).
|
|
7
|
+
*
|
|
8
|
+
* @returns {string} 64-character hex string.
|
|
9
|
+
*/
|
|
10
|
+
function generateServerSeed() {
|
|
11
|
+
return (0, node_crypto_1.randomBytes)(32).toString('hex');
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=generate-server-seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-server-seed.js","sourceRoot":"","sources":["../../src/utils/generate-server-seed.ts"],"names":[],"mappings":";;AAOA,gDAEC;AATD,6CAA0C;AAE1C;;;;GAIG;AACH,SAAgB,kBAAkB;IAChC,OAAO,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateServerSeed = exports.createEntropyInput = void 0;
|
|
4
|
+
var create_entropy_input_1 = require("./create-entropy-input");
|
|
5
|
+
Object.defineProperty(exports, "createEntropyInput", { enumerable: true, get: function () { return create_entropy_input_1.createEntropyInput; } });
|
|
6
|
+
var generate_server_seed_1 = require("./generate-server-seed");
|
|
7
|
+
Object.defineProperty(exports, "generateServerSeed", { enumerable: true, get: function () { return generate_server_seed_1.generateServerSeed; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;AAAA,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA;AAC3B,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@1fun-games/rng",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": "1fun provider ltd",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"igaming-certification",
|
|
8
|
+
"gaming-laboratories-international",
|
|
9
|
+
"gaminglabs",
|
|
10
|
+
"itech-labs",
|
|
11
|
+
"gli-19",
|
|
12
|
+
"csprng",
|
|
13
|
+
"rng",
|
|
14
|
+
"hmac-drbg"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://github.com/1fun-games/rng#readme",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/1fun-games/rng.git"
|
|
20
|
+
},
|
|
21
|
+
"main": "dist/index.js",
|
|
22
|
+
"types": "dist/index.d.ts",
|
|
23
|
+
"files": ["dist"],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "rimraf dist && tsc --build tsconfig.json",
|
|
26
|
+
"lint": "eslint --ext .ts,.js,.mjs,mts .",
|
|
27
|
+
"lint:fix": "eslint --ext .ts,.js,.mjs,mts . --fix",
|
|
28
|
+
"test": "jest"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@eslint/compat": "~1.3.2",
|
|
32
|
+
"@eslint/eslintrc": "~3.3.1",
|
|
33
|
+
"@eslint/js": "~9.35.0",
|
|
34
|
+
"@types/jest": "~30.0.0",
|
|
35
|
+
"@types/node": "~24.3.1",
|
|
36
|
+
"@types/yargs": "~17.0.33",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "~8.43.0",
|
|
38
|
+
"@typescript-eslint/parser": "~8.43.0",
|
|
39
|
+
"eslint": "~9.35.0",
|
|
40
|
+
"eslint-config-prettier": "~10.1.8",
|
|
41
|
+
"eslint-import-resolver-typescript": "~4.4.4",
|
|
42
|
+
"eslint-plugin-import": "~2.32.0",
|
|
43
|
+
"eslint-plugin-prettier": "~5.5.4",
|
|
44
|
+
"expect": "~30.1.2",
|
|
45
|
+
"jest": "~30.1.3",
|
|
46
|
+
"rimraf": "~6.0.1",
|
|
47
|
+
"ts-jest": "~29.4.1",
|
|
48
|
+
"ts-node": "~10.9.2",
|
|
49
|
+
"typescript": "~5.9.2",
|
|
50
|
+
"yargs": "~18.0.0"
|
|
51
|
+
}
|
|
52
|
+
}
|