@theqrl/qrl-cryptography 0.1.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 ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Patricio Palladino, Paul Miller, ethereum-cryptography contributors
4
+ Copyright (c) 2024 The QRL Contributors
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the “Software”), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,258 @@
1
+ # @theqrl/qrl-cryptography
2
+
3
+ All pure-js cryptographic primitives normally used when
4
+ developing Javascript / TypeScript applications and tools for QRL.
5
+
6
+ The cryptographic primitives included are:
7
+
8
+ * [Hashes: keccak-256](#hasheskeccak-256)
9
+ * [KDFs: Argon2id](#kdfs-argon2id)
10
+ * [CSPRNG (Cryptographically strong pseudorandom number generator)](#csprng-cryptographically-strong-pseudorandom-number-generator)
11
+ * [AES Encryption](#aes-encryption)
12
+ * [ML-DSA-87](#ml-dsa-87)
13
+
14
+ ## Usage
15
+
16
+ Use NPM / Yarn in node.js / browser:
17
+
18
+ ```bash
19
+ # NPM
20
+ npm install @theqrl/qrl-cryptography
21
+
22
+ # Yarn
23
+ yarn add @theqrl/qrl-cryptography
24
+ ```
25
+
26
+ See [browser usage](#browser-usage) for information on using the package with major Javascript bundlers. It is
27
+ tested with **Webpack, Rollup and Parcel**.
28
+
29
+ This package has no single entry-point, but submodule for each cryptographic
30
+ primitive. Read each primitive's section of this document to learn how to use
31
+ them.
32
+
33
+ The reason for this is that importing everything from a single file will lead to
34
+ huge bundles when using this package for the web. This could be avoided through
35
+ tree-shaking, but the possibility of it not working properly on one of
36
+ [the supported bundlers](#browser-usage) is too high.
37
+
38
+ ```js
39
+ // Hashes
40
+ const { keccak256 } = require("@theqrl/qrl-cryptography/keccak");
41
+
42
+ // KDFs
43
+ const { argon2idSync } = require("@theqrl/qrl-cryptography/argon2id");
44
+
45
+ // Random
46
+ const { getRandomBytesSync } = require("@theqrl/qrl-cryptography/random");
47
+
48
+ // AES encryption
49
+ const { encrypt } = require("@theqrl/qrl-cryptography/aes");
50
+
51
+ // ML-DSA-87
52
+ const { ml_dsa87 } = require("@theqrl/qrl-cryptography/ml_dsa87");
53
+
54
+ // utilities
55
+ const { hexToBytes, toHex, utf8ToBytes } = require("@theqrl/qrl-cryptography/utils");
56
+ ```
57
+
58
+ ## Hashes: keccak-256
59
+ ```typescript
60
+ function keccak256(msg: Uint8Array): Uint8Array;
61
+ ```
62
+
63
+ Exposes following cryptographic hash functions:
64
+
65
+ - keccak-256 variant of SHA3 (also `keccak224`, `keccak384`,
66
+ and `keccak512`)
67
+
68
+ ```js
69
+ const { keccak256, keccak224, keccak384, keccak512 } = require("@theqrl/qrl-cryptography/keccak");
70
+
71
+ keccak256(Uint8Array.from([1, 2, 3]))
72
+
73
+ // Can be used with strings
74
+ const { utf8ToBytes } = require("@theqrl/qrl-cryptography/utils");
75
+ keccak256(utf8ToBytes("abc"))
76
+
77
+ // If you need hex
78
+ const { bytesToHex as toHex } = require("@theqrl/qrl-cryptography/utils");
79
+ toHex(keccak256(utf8ToBytes("abc")))
80
+ ```
81
+
82
+ ## KDFs: Argon2id
83
+
84
+ ```ts
85
+ function argon2id(password: Uint8Array, salt: Uint8Array, t: number, m: number, p: number, dkLen: number, onProgress?: (progress: number) => void): Promise<Uint8Array>;
86
+ function argon2idSync(password: Uint8Array, salt: Uint8Array, t: number, m: number, p: number, dkLen: number, onProgress?: (progress: number) => void): Uint8Array;
87
+ ```
88
+
89
+ The `argon2id` submodule has two functions implementing the Argon2id key
90
+ derivation algorithm in synchronous and asynchronous ways. This algorithm is
91
+ very slow, and using the synchronous version in the browser is not recommended,
92
+ as it will block its main thread and hang your UI.
93
+
94
+ ```js
95
+ const { argon2id } = require("@theqrl/qrl-cryptography/argon2id");
96
+ const { utf8ToBytes } = require("@theqrl/qrl-cryptography/utils");
97
+ console.log(await argon2id(utf8ToBytes("password"), utf8ToBytes("salt"), 8, 262144, 1, 32));
98
+ ```
99
+
100
+ ## CSPRNG (Cryptographically strong pseudorandom number generator)
101
+
102
+ ```ts
103
+ function getRandomBytes(bytes: number): Promise<Uint8Array>;
104
+ function getRandomBytesSync(bytes: number): Uint8Array;
105
+ ```
106
+
107
+ The `random` submodule has functions to generate cryptographically strong
108
+ pseudo-random data in synchronous and asynchronous ways.
109
+
110
+ Backed by [`crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) in browser and by [`crypto.randomBytes`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) in node.js. If backends are somehow not available, the module would throw an error and won't work, as keeping them working would be insecure.
111
+
112
+ ```js
113
+ const { getRandomBytesSync } = require("@theqrl/qrl-cryptography/random");
114
+ console.log(getRandomBytesSync(32));
115
+ ```
116
+
117
+ ## AES Encryption
118
+
119
+ ```ts
120
+ function encrypt(msg: Uint8Array, key: Uint8Array, iv: Uint8Array, mode = "aes-256-gcm", pkcs7PaddingEnabled = true): Promise<Uint8Array>;
121
+ function decrypt(cypherText: Uint8Array, key: Uint8Array, iv: Uint8Array, mode = "aes-256-gcm", pkcs7PaddingEnabled = true): Promise<Uint8Array>;
122
+ ```
123
+
124
+ The `aes` submodule contains encryption and decryption functions implementing
125
+ the [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
126
+ algorithm.
127
+
128
+ ### Encrypting with passwords
129
+
130
+ AES is not supposed to be used directly with a password. Doing that will
131
+ compromise your users' security.
132
+
133
+ The `key` parameters in this submodule are meant to be strong cryptographic
134
+ keys. If you want to obtain such a key from a password, please use a
135
+ [key derivation function](https://en.wikipedia.org/wiki/Key_derivation_function)
136
+ like [argon2id](#kdfs-argon2id).
137
+
138
+ ### Operation modes
139
+
140
+ This submodule works with different [block cipher modes of operation](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation). If you are using this module in a new
141
+ application, we recommend using the default.
142
+
143
+ While this module may work with any mode supported by OpenSSL, we only test it
144
+ with `aes-256-gcm`. If you use another module a warning will be printed in the
145
+ console.
146
+
147
+ We only recommend using `aes-256-gcm` to decrypt already encrypted data.
148
+
149
+ ### Padding plaintext messages
150
+
151
+ Some operation modes require the plaintext message to be a multiple of `16`. If
152
+ that isn't the case, your message has to be padded.
153
+
154
+ By default, this module automatically pads your messages according to [PKCS#7](https://tools.ietf.org/html/rfc2315).
155
+ Note that this padding scheme always adds at least 1 byte of padding. If you
156
+ are unsure what anything of this means, we **strongly** recommend you to use
157
+ the defaults.
158
+
159
+ If you need to encrypt without padding or want to use another padding scheme,
160
+ you can disable PKCS#7 padding by passing `false` as the last argument and
161
+ handling padding yourself. Note that if you do this and your operation mode
162
+ requires padding, `encrypt` will throw if your plaintext message isn't a
163
+ multiple of `16`.
164
+
165
+ This option is only present to enable the decryption of already encrypted data.
166
+ To encrypt new data, we recommend using the default.
167
+
168
+ ### How to use the IV parameter
169
+
170
+ The `iv` parameter of the `encrypt` function must be unique, or the security
171
+ of the encryption algorithm can be compromised.
172
+
173
+ You can generate a new `iv` using the `random` module.
174
+
175
+ Note that to decrypt a value, you have to provide the same `iv` used to encrypt
176
+ it.
177
+
178
+ ### How to handle errors with this module
179
+
180
+ Sensitive information can be leaked via error messages when using this module.
181
+ To avoid this, you should make sure that the errors you return don't
182
+ contain the exact reason for the error. Instead, errors must report general
183
+ encryption/decryption failures.
184
+
185
+ Note that implementing this can mean catching all errors that can be thrown
186
+ when calling on of this module's functions, and just throwing a new generic
187
+ exception.
188
+
189
+ ### Example usage
190
+
191
+ ```js
192
+ const { encrypt } = require("@theqrl/qrl-cryptography/aes");
193
+ const { hexToBytes, utf8ToBytes } = require("@theqrl/qrl-cryptography/utils");
194
+
195
+ console.log(
196
+ encrypt(
197
+ utf8ToBytes("message"),
198
+ hexToBytes("2b7e151628aed2a6abf7158809cf4f3c"),
199
+ hexToBytes("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
200
+ )
201
+ );
202
+ ```
203
+
204
+ ## ML-DSA-87
205
+
206
+ ```ts
207
+ function keygen(seed: Uint8Array): { publicKey: Uint8Array; secretKey: Uint8Array };
208
+ function sign(secretKey: Uint8Array, message: Uint8Array, ctx: Uint8Array): Uint8Array;
209
+ function verify(publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array, ctx: Uint8Array): boolean;
210
+ ```
211
+
212
+ The `ml_dsa87` submodule provides the ML-DSA-87 (FIPS 204) post-quantum digital signature scheme, powered by [`@theqrl/mldsa87`](https://www.npmjs.com/package/@theqrl/mldsa87).
213
+
214
+ ```js
215
+ const { ml_dsa87 } = require("@theqrl/qrl-cryptography/ml_dsa87");
216
+ const { utf8ToBytes } = require("@theqrl/qrl-cryptography/utils");
217
+
218
+ // Generate a key pair
219
+ const { publicKey, secretKey } = ml_dsa87.keygen(seed);
220
+
221
+ // Sign a message
222
+ const ctx = utf8ToBytes("context");
223
+ const msg = utf8ToBytes("hello");
224
+ const signature = ml_dsa87.sign(secretKey, msg, ctx);
225
+
226
+ // Verify a signature
227
+ const isValid = ml_dsa87.verify(publicKey, msg, signature, ctx);
228
+ ```
229
+
230
+ ## Browser usage
231
+
232
+ ### Rollup setup
233
+
234
+ Using this library with Rollup requires the following plugins:
235
+
236
+ * [`@rollup/plugin-commonjs`](https://www.npmjs.com/package/@rollup/plugin-commonjs)
237
+ * [`@rollup/plugin-node-resolve`](https://www.npmjs.com/package/@rollup/plugin-node-resolve)
238
+
239
+ These can be used by setting your `plugins` array like this:
240
+
241
+ ```js
242
+ plugins: [
243
+ commonjs(),
244
+ resolve({
245
+ browser: true,
246
+ preferBuiltins: false,
247
+ }),
248
+ ]
249
+ ```
250
+
251
+ ## License
252
+
253
+ `qrl-cryptography` is released under The MIT License (MIT)
254
+
255
+ Copyright (c) 2021 Patricio Palladino, Paul Miller, ethereum-cryptography contributors
256
+ Copyright (c) 2024 The QRL Contributors
257
+
258
+ See [LICENSE](./LICENSE) file.
package/aes.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function encrypt(msg: Uint8Array, key: Uint8Array, iv: Uint8Array, mode?: string, pkcs7PaddingEnabled?: boolean): Promise<Uint8Array>;
2
+ export declare function decrypt(cypherText: Uint8Array, key: Uint8Array, iv: Uint8Array, mode?: string, pkcs7PaddingEnabled?: boolean): Promise<Uint8Array>;
package/aes.js ADDED
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decrypt = exports.encrypt = void 0;
4
+ const crypto_1 = require("@noble/hashes/crypto");
5
+ const utils_1 = require("./utils");
6
+ const crypto = { web: crypto_1.crypto };
7
+ function validateOpt(key, iv, mode) {
8
+ if (!mode.startsWith("aes-")) {
9
+ throw new Error(`AES submodule doesn't support mode ${mode}`);
10
+ }
11
+ if (iv.length !== 12) {
12
+ throw new Error("AES: wrong IV length");
13
+ }
14
+ if (mode.startsWith("aes-256") && key.length !== 32) {
15
+ throw new Error("AES: wrong key length");
16
+ }
17
+ }
18
+ async function getBrowserKey(mode, key, iv) {
19
+ if (!crypto.web) {
20
+ throw new Error("Browser crypto not available.");
21
+ }
22
+ let keyMode;
23
+ if (["aes-256-gcm"].includes(mode)) {
24
+ keyMode = "gcm";
25
+ }
26
+ if (!keyMode) {
27
+ throw new Error("AES: unsupported mode");
28
+ }
29
+ const wKey = await crypto.web.subtle.importKey("raw", key, { name: `AES-${keyMode.toUpperCase()}`, length: key.length * 8 }, true, ["encrypt", "decrypt"]);
30
+ // TODO(rgeraldes24): missing fields
31
+ // node.js uses whole 128 bit as a counter, without nonce, instead of 64 bit
32
+ // recommended by NIST SP800-38A
33
+ return [wKey, { name: `aes-${keyMode}`, iv }];
34
+ }
35
+ async function encrypt(msg, key, iv, mode = "aes-256-gcm", pkcs7PaddingEnabled = true) {
36
+ validateOpt(key, iv, mode);
37
+ if (crypto.web) {
38
+ const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
39
+ const cipher = await crypto.web.subtle.encrypt(wOpt, wKey, msg);
40
+ let res = new Uint8Array(cipher);
41
+ return res;
42
+ }
43
+ else if (crypto.node) {
44
+ const cipher = crypto.node.createCipheriv(mode, key, iv);
45
+ cipher.setAutoPadding(pkcs7PaddingEnabled);
46
+ return (0, utils_1.concatBytes)(cipher.update(msg), cipher.final());
47
+ }
48
+ else {
49
+ throw new Error("The environment doesn't have AES module");
50
+ }
51
+ }
52
+ exports.encrypt = encrypt;
53
+ async function decrypt(cypherText, key, iv, mode = "aes-256-gcm", pkcs7PaddingEnabled = true) {
54
+ validateOpt(key, iv, mode);
55
+ if (crypto.web) {
56
+ const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
57
+ const msg = await crypto.web.subtle.decrypt(wOpt, wKey, cypherText);
58
+ const msgBytes = new Uint8Array(msg);
59
+ return msgBytes;
60
+ }
61
+ else if (crypto.node) {
62
+ const decipher = crypto.node.createDecipheriv(mode, key, iv);
63
+ decipher.setAutoPadding(pkcs7PaddingEnabled);
64
+ return (0, utils_1.concatBytes)(decipher.update(cypherText), decipher.final());
65
+ }
66
+ else {
67
+ throw new Error("The environment doesn't have AES module");
68
+ }
69
+ }
70
+ exports.decrypt = decrypt;
package/argon2id.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ type OnProgressCallback = (progress: number) => void;
2
+ export declare function argon2id(password: Uint8Array, salt: Uint8Array, t: number, m: number, p: number, dkLen: number, onProgress?: OnProgressCallback): Promise<Uint8Array>;
3
+ export declare function argon2idSync(password: Uint8Array, salt: Uint8Array, t: number, m: number, p: number, dkLen: number, onProgress?: OnProgressCallback): Uint8Array;
4
+ export {};
package/argon2id.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.argon2idSync = exports.argon2id = void 0;
4
+ const argon2_1 = require("@noble/hashes/argon2");
5
+ const utils_1 = require("./utils");
6
+ async function argon2id(password, salt, t, m, p, dkLen, onProgress) {
7
+ (0, utils_1.assertBytes)(password);
8
+ (0, utils_1.assertBytes)(salt);
9
+ return (0, argon2_1.argon2idAsync)(password, salt, { t, m, p, dkLen, onProgress });
10
+ }
11
+ exports.argon2id = argon2id;
12
+ function argon2idSync(password, salt, t, m, p, dkLen, onProgress) {
13
+ (0, utils_1.assertBytes)(password);
14
+ (0, utils_1.assertBytes)(salt);
15
+ return (0, argon2_1.argon2id)(password, salt, { t, m, p, dkLen, onProgress });
16
+ }
17
+ exports.argon2idSync = argon2idSync;
@@ -0,0 +1,25 @@
1
+ const tseslint = require("@typescript-eslint/eslint-plugin");
2
+ const tsparser = require("@typescript-eslint/parser");
3
+ const prettier = require("eslint-plugin-prettier");
4
+
5
+ module.exports = [
6
+ {
7
+ files: ["**/*.ts"],
8
+ languageOptions: {
9
+ parser: tsparser,
10
+ },
11
+ plugins: {
12
+ "@typescript-eslint": tseslint,
13
+ prettier: prettier,
14
+ },
15
+ rules: {
16
+ ...tseslint.configs.recommended.rules,
17
+ "@typescript-eslint/no-explicit-any": "warn",
18
+ "@typescript-eslint/no-unused-vars": "warn",
19
+ "prettier/prettier": "error",
20
+ },
21
+ },
22
+ {
23
+ ignores: ["node_modules", "test-builds", "*.js", "*.d.ts"],
24
+ },
25
+ ];
package/index.d.ts ADDED
File without changes
package/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ throw new Error("This package has no entry-point. Please consult the README.md to learn how to use it.");
package/keccak.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { Keccak } from "@noble/hashes/sha3";
2
+ import { Hash } from "@noble/hashes/utils";
3
+ interface K256 {
4
+ (data: Uint8Array): Uint8Array;
5
+ create(): Hash<Keccak>;
6
+ }
7
+ export declare const keccak224: (msg: Uint8Array) => Uint8Array;
8
+ export declare const keccak256: K256;
9
+ export declare const keccak384: (msg: Uint8Array) => Uint8Array;
10
+ export declare const keccak512: (msg: Uint8Array) => Uint8Array;
11
+ export {};
package/keccak.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.keccak512 = exports.keccak384 = exports.keccak256 = exports.keccak224 = void 0;
4
+ const sha3_1 = require("@noble/hashes/sha3");
5
+ const utils_1 = require("./utils");
6
+ exports.keccak224 = (0, utils_1.wrapHash)(sha3_1.keccak_224);
7
+ exports.keccak256 = (() => {
8
+ const k = (0, utils_1.wrapHash)(sha3_1.keccak_256);
9
+ k.create = sha3_1.keccak_256.create;
10
+ return k;
11
+ })();
12
+ exports.keccak384 = (0, utils_1.wrapHash)(sha3_1.keccak_384);
13
+ exports.keccak512 = (0, utils_1.wrapHash)(sha3_1.keccak_512);
package/ml_dsa87.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ export declare const ml_dsa87: {
2
+ keygen(seed: Uint8Array): {
3
+ publicKey: Uint8Array;
4
+ secretKey: Uint8Array;
5
+ };
6
+ sign(secretKey: Uint8Array, message: Uint8Array, ctx: Uint8Array): Uint8Array;
7
+ verify(publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array, ctx: Uint8Array): boolean;
8
+ };
package/ml_dsa87.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ml_dsa87 = void 0;
4
+ const mldsa87_1 = require("@theqrl/mldsa87");
5
+ exports.ml_dsa87 = {
6
+ keygen(seed) {
7
+ const pk = new Uint8Array(mldsa87_1.CryptoPublicKeyBytes);
8
+ const sk = new Uint8Array(mldsa87_1.CryptoSecretKeyBytes);
9
+ (0, mldsa87_1.cryptoSignKeypair)(seed, pk, sk);
10
+ return { publicKey: pk, secretKey: sk };
11
+ },
12
+ sign(secretKey, message, ctx) {
13
+ const sig = new Uint8Array(mldsa87_1.CryptoBytes);
14
+ (0, mldsa87_1.cryptoSignSignature)(sig, message, secretKey, false, ctx);
15
+ return sig;
16
+ },
17
+ verify(publicKey, message, signature, ctx) {
18
+ return (0, mldsa87_1.cryptoSignVerify)(signature, message, publicKey, ctx);
19
+ },
20
+ };
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@theqrl/qrl-cryptography",
3
+ "version": "0.1.0",
4
+ "description": "All the cryptographic primitives used in QRL",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/theQRL/js-qrl-cryptography.git"
8
+ },
9
+ "license": "MIT",
10
+ "main": "./index.js",
11
+ "files": [
12
+ "*.js",
13
+ "*.d.ts"
14
+ ],
15
+ "dependencies": {
16
+ "@noble/curves": "1.0.0",
17
+ "@noble/hashes": "1.6.1",
18
+ "@theqrl/mldsa87": "2.0.1"
19
+ },
20
+ "browser": {
21
+ "crypto": false
22
+ },
23
+ "sideEffects": false,
24
+ "scripts": {
25
+ "prepare": "npm run build",
26
+ "build": "npm-run-all build:tsc",
27
+ "build:tsc": "tsc --project tsconfig.prod.json",
28
+ "test": "npm-run-all test:node",
29
+ "test:node": "mocha",
30
+ "clean": "rimraf test-builds '*.js' '*.js.map' '*.d.ts' '*.d.ts.map' 'src/**/*.js'",
31
+ "lint": "eslint",
32
+ "lint:fix": "eslint --fix",
33
+ "browser-tests": "npm-run-all browser-tests:build browser-tests:test",
34
+ "browser-tests:build": "bash -x ./scripts/build-browser-tests.sh",
35
+ "browser-tests:test": "npm-run-all browser-tests:test-parcel browser-tests:test-webpack browser-tests:test-rollup",
36
+ "browser-tests:test-parcel": "karma start --single-run --browsers ChromeHeadless test/karma.parcel.conf.js",
37
+ "browser-tests:test-webpack": "karma start --single-run --browsers ChromeHeadless test/karma.webpack.conf.js",
38
+ "browser-tests:test-rollup": "karma start --single-run --browsers ChromeHeadless test/karma.rollup.conf.js"
39
+ },
40
+ "devDependencies": {
41
+ "@rollup/plugin-commonjs": "29.0.2",
42
+ "@rollup/plugin-node-resolve": "16.0.3",
43
+ "@types/estree": "1.0.8",
44
+ "@types/mocha": "9.1.1",
45
+ "@types/node": "18.15.11",
46
+ "@typescript-eslint/eslint-plugin": "8.58.0",
47
+ "@typescript-eslint/parser": "8.58.0",
48
+ "eslint": "9.26.0",
49
+ "eslint-plugin-prettier": "5.5.5",
50
+ "karma": "6.4.0",
51
+ "karma-chrome-launcher": "3.1.1",
52
+ "karma-mocha": "2.0.1",
53
+ "karma-mocha-reporter": "2.2.5",
54
+ "mocha": "10.0.0",
55
+ "npm-run-all": "4.1.5",
56
+ "parcel": "2.6.2",
57
+ "prettier": "3.8.1",
58
+ "rimraf": "~3.0.2",
59
+ "rollup": "4.59.0",
60
+ "ts-node": "10.9.1",
61
+ "typescript": "5.0.2",
62
+ "webpack": "5.104.1",
63
+ "webpack-cli": "4.10"
64
+ },
65
+ "keywords": [
66
+ "qrl",
67
+ "cryptography",
68
+ "digital signature",
69
+ "hash",
70
+ "encryption",
71
+ "prng",
72
+ "keccak",
73
+ "argon2id",
74
+ "aes",
75
+ "advanced encryption standar"
76
+ ],
77
+ "targets": {
78
+ "parcel_tests": {
79
+ "context": "browser"
80
+ }
81
+ }
82
+ }
package/random.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function getRandomBytesSync(bytes: number): Uint8Array;
2
+ export declare function getRandomBytes(bytes: number): Promise<Uint8Array>;
package/random.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRandomBytes = exports.getRandomBytesSync = void 0;
4
+ const utils_1 = require("@noble/hashes/utils");
5
+ function getRandomBytesSync(bytes) {
6
+ return (0, utils_1.randomBytes)(bytes);
7
+ }
8
+ exports.getRandomBytesSync = getRandomBytesSync;
9
+ async function getRandomBytes(bytes) {
10
+ return (0, utils_1.randomBytes)(bytes);
11
+ }
12
+ exports.getRandomBytes = getRandomBytes;
package/utils.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ declare const assertBytes: typeof import("@noble/hashes/_assert").abytes;
2
+ export { /*assertBool,*/ assertBytes };
3
+ export { bytesToHex, bytesToHex as toHex, concatBytes, createView, utf8ToBytes, } from "@noble/hashes/utils";
4
+ export declare function bytesToUtf8(data: Uint8Array): string;
5
+ export declare function hexToBytes(data: string): Uint8Array;
6
+ export declare function equalsBytes(a: Uint8Array, b: Uint8Array): boolean;
7
+ export declare function wrapHash(hash: (msg: Uint8Array) => Uint8Array): (msg: Uint8Array) => Uint8Array;
8
+ export declare const crypto: {
9
+ node?: any;
10
+ web?: Crypto;
11
+ };
package/utils.js ADDED
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.crypto = exports.wrapHash = exports.equalsBytes = exports.hexToBytes = exports.bytesToUtf8 = exports.utf8ToBytes = exports.createView = exports.concatBytes = exports.toHex = exports.bytesToHex = exports.assertBytes = void 0;
7
+ // buf.toString('hex') -> toHex(buf)
8
+ const _assert_1 = __importDefault(require("@noble/hashes/_assert"));
9
+ const utils_1 = require("@noble/hashes/utils");
10
+ // const assertBool = assert.bool;
11
+ const assertBytes = _assert_1.default.bytes;
12
+ exports.assertBytes = assertBytes;
13
+ var utils_2 = require("@noble/hashes/utils");
14
+ Object.defineProperty(exports, "bytesToHex", { enumerable: true, get: function () { return utils_2.bytesToHex; } });
15
+ Object.defineProperty(exports, "toHex", { enumerable: true, get: function () { return utils_2.bytesToHex; } });
16
+ Object.defineProperty(exports, "concatBytes", { enumerable: true, get: function () { return utils_2.concatBytes; } });
17
+ Object.defineProperty(exports, "createView", { enumerable: true, get: function () { return utils_2.createView; } });
18
+ Object.defineProperty(exports, "utf8ToBytes", { enumerable: true, get: function () { return utils_2.utf8ToBytes; } });
19
+ // buf.toString('utf8') -> bytesToUtf8(buf)
20
+ function bytesToUtf8(data) {
21
+ if (!(data instanceof Uint8Array)) {
22
+ throw new TypeError(`bytesToUtf8 expected Uint8Array, got ${typeof data}`);
23
+ }
24
+ return new TextDecoder().decode(data);
25
+ }
26
+ exports.bytesToUtf8 = bytesToUtf8;
27
+ function hexToBytes(data) {
28
+ const sliced = data.startsWith("0x") ? data.substring(2) : data;
29
+ return (0, utils_1.hexToBytes)(sliced);
30
+ }
31
+ exports.hexToBytes = hexToBytes;
32
+ // buf.equals(buf2) -> equalsBytes(buf, buf2)
33
+ function equalsBytes(a, b) {
34
+ if (a.length !== b.length) {
35
+ return false;
36
+ }
37
+ for (let i = 0; i < a.length; i++) {
38
+ if (a[i] !== b[i]) {
39
+ return false;
40
+ }
41
+ }
42
+ return true;
43
+ }
44
+ exports.equalsBytes = equalsBytes;
45
+ // Internal utils
46
+ function wrapHash(hash) {
47
+ return (msg) => {
48
+ _assert_1.default.bytes(msg);
49
+ return hash(msg);
50
+ };
51
+ }
52
+ exports.wrapHash = wrapHash;
53
+ exports.crypto = (() => {
54
+ const webCrypto = typeof self === "object" && "crypto" in self ? self.crypto : undefined;
55
+ const nodeRequire = typeof module !== "undefined" &&
56
+ typeof module.require === "function" &&
57
+ module.require.bind(module);
58
+ return {
59
+ node: nodeRequire && !webCrypto ? nodeRequire("crypto") : undefined,
60
+ web: webCrypto,
61
+ };
62
+ })();