@lumjs/encode 1.2.0 → 2.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.
@@ -1,171 +0,0 @@
1
- /**
2
- * Crypto-JS helpers.
3
- *
4
- * Uses a lot of magic proxy abilities.
5
- * Look at the `test/020-crypto.js` for examples.
6
- *
7
- * The top-level properties are *case-sensitive*, as
8
- * is standard in Javascript. In some cases this means
9
- * there are two names that differ only in case, such as
10
- * `crypto.hash` (a proxy object returning hashing functions)
11
- * versus `crypto.HASH` (a proxy object returning object instaces).
12
- *
13
- * The child properties of any *proxy object* properties
14
- * are *case-insensitive*. So `crypto.hash.sha256` is the
15
- * same as `crypto.hash.SHA256`.
16
- *
17
- * @module @lumjs/encode/crypto
18
- */
19
- const {def} = require('@lumjs/core/types');
20
-
21
- /**
22
- * A link to the `crypto-js/core` library.
23
- *
24
- * This corresponds to the `CryptoJS` global in the original
25
- * implementation, and is used by all the other modules
26
- * in the `crypto-js` collection.
27
- *
28
- * @alias module:@lumjs/encode/crypto.core
29
- */
30
- const cc = require('crypto-js/core');
31
- exports.core = cc;
32
-
33
- /**
34
- * A link to the `crypto-js/core.lib.WordArray` library.
35
- *
36
- * We always load the `lib-typedarray` plugin that allows
37
- * conversion from `WordArray` objects.
38
- */
39
- exports.WordArray = require('crypto-js/lib-typedarrays');
40
-
41
- /**
42
- * Our custom module loader.
43
- *
44
- * Can be used as a `function` itself, but generally one of the
45
- * child methods is a lot simpler, and works around weird
46
- * gotchyas in the `crypto-js` library.
47
- *
48
- * All of the *proxy objects* use this as the underlying
49
- * target object, and each of them corresponds to one of
50
- * the methods from this.
51
- *
52
- * @see {@link module:@lumjs/encode/crypto/load}
53
- * @see {@link module:@lumjs/encode/crypto/load.load}
54
- */
55
- exports.load = require('./load');
56
-
57
- // A list of loader properties to *not* make proxies for.
58
- const NO_LOAD = ['load'];
59
-
60
- // Make proxy objects for the loader properties.
61
- for (const loader in exports.load)
62
- {
63
- if (NO_LOAD.includes(loader)) continue;
64
- exports[loader] = new Proxy(exports.load,
65
- {
66
- get(load, lib)
67
- {
68
- return load[loader](lib);
69
- }
70
- });
71
- }
72
-
73
- /**
74
- * A proxy object for building a progressive hashing instance.
75
- *
76
- * Any property of this should be the name of a *Hash algorithm*.
77
- *
78
- * Each property is a `function` which takes an optional `object`
79
- * parameter called `options`, and will call `load.hash(algorithm, options)`,
80
- * which will return a progressive hashing instance.
81
- *
82
- * For a non-progressive hashing function, use the lowercase
83
- * [hash]{@link module:@lumjs/encode/crypto.hash} property instead.
84
- */
85
- exports.HASH = new Proxy(exports.load,
86
- {
87
- get(load, lib)
88
- {
89
- return (options => load.hash(lib, options ?? {}));
90
- }
91
- });
92
-
93
- /**
94
- * A proxy object for building a progressive **HMAC** hashing instance.
95
- *
96
- * Any property of this should be the name of a *Hash algorithm*.
97
- *
98
- * Each property is a `function` which takes a mandatory `string`
99
- * parameter called `secret`, and will call `load.hmac(algorithm, secret)`,
100
- * which will return a progressive HMAC hashing instance.
101
- *
102
- * For a non-progressive HMAC hashing function, use the lowercase
103
- * [hmac]{@link module:@lumjs/encode/crypto.hmac} property instead.
104
- */
105
- exports.HMAC = new Proxy(exports.load,
106
- {
107
- get(load, lib)
108
- {
109
- return (secret => load.hmac(lib, secret));
110
- }
111
- });
112
-
113
- /**
114
- * A proxy object for loading Hashing functions.
115
- *
116
- * Any property of this should be the name of a *Hash algorithm*,
117
- * and the property will return the corresponding hashing function.
118
- *
119
- * For a progressive hashing instance, use the uppercase
120
- * [HASH]{@link module:@lumjs/encode/crypto.HASH} property instead.
121
- *
122
- * @name module:@lumjs/encode/crypto.hash
123
- */
124
-
125
- /**
126
- * A proxy object for loading HMAC hashing functions.
127
- *
128
- * Any property of this should be the name of a *Hash algorithm*,
129
- * and the property will return the corresponding HMAC hashing function.
130
- *
131
- * For a progressive HMAC hashing instance, use the uppercase
132
- * [HMAC]{@link module:@lumjs/encode/crypto.HMAC} property instead.
133
- *
134
- * @name module:@lumjs/encode/crypto.hmac
135
- */
136
-
137
- /**
138
- * A proxy object for loading Cipher libraries.
139
- *
140
- * @name module:@lumjs/encode/crypto.cipher
141
- */
142
-
143
- /**
144
- * A proxy object for loading Algorithm libraries.
145
- *
146
- * @name module:@lumjs/encode/crypto.algo
147
- */
148
-
149
- /**
150
- * A proxy object for loading Encoding libraries.
151
- *
152
- * @name module:@lumjs/encode/crypto.enc
153
- */
154
-
155
- /**
156
- * A proxy object for loading Padding plugins.
157
- *
158
- * @name module:@lumjs/encode/crypto.pad
159
- */
160
-
161
- /**
162
- * A proxy object for loading Mode plugins.
163
- *
164
- * @name module:@lumjs/encode/crypto.mode
165
- */
166
-
167
- /**
168
- * A proxy object for loading Format plugins.
169
- *
170
- * @name module:@lumjs/encode/crypto.format
171
- */
@@ -1,344 +0,0 @@
1
- const {F,S,isObj} = require('@lumjs/core/types');
2
-
3
- /**
4
- * Crypto-JS Module Loader
5
- *
6
- * Uses some dark magic to normalize any weirdness, bugs,
7
- * or gotchyas in the upsteam library.
8
- *
9
- * @module @lumjs/encode/crypto/load
10
- */
11
-
12
- const cc = require('crypto-js/core');
13
-
14
- /**
15
- * Load and return a specific `crypto-js` module.
16
- *
17
- * This is a wrapper for `require()` that prefixes
18
- * the `crypto-js/` package namespace.
19
- *
20
- * Generally you should never have to call this manually.
21
- * Instead use one of the more specialized methods.
22
- *
23
- * Note that **this** is the actual *default export* from
24
- * the `load` module, and all the other functions are
25
- * child properties of it.
26
- *
27
- * @param {string} name - The name of the module.
28
- *
29
- * @param {boolean} [toLower=true] Enforce lowercase names?
30
- *
31
- * If `true` (the default value), the `name` will be
32
- * normalized to *lowercase* as is expected by the library.
33
- *
34
- * @returns {(object|function)} The module content.
35
- *
36
- * Some `crypto-js` modules return a child `object`, some return
37
- * a child `function`, and some return the `crypto-js/core` object.
38
- * The wide difference in return values is part of why this
39
- * method should not be used directly.
40
- *
41
- * @alias module:@lumjs/encode/crypto/load.load
42
- */
43
- function load(name, toLower=true)
44
- {
45
- if (toLower)
46
- name = name.toLowerCase();
47
- return require('crypto-js/'+name);
48
- }
49
-
50
- // Export the load function, and make all other functions properties of it.
51
- module.exports = exports = load;
52
- load.load = load; // Fuckery.
53
-
54
- /**
55
- * Get a Hashing function or progressive instance.
56
- *
57
- * @param {string} name - The name of the algorithm.
58
- *
59
- * Hashing algorithms supported by `crypto-js`:
60
- *
61
- * - MD5
62
- * - SHA-1
63
- * - SHA-256
64
- * - SHA-512
65
- * - SHA-224
66
- * - SHA-384
67
- * - SHA-3
68
- * - RIPEMD-160
69
- *
70
- * You can omit the `-` characters, and the parameter is
71
- * case-insensitive.
72
- *
73
- * @param {(boolean|object)} [instance=false] Return an instance?
74
- *
75
- * If this is `true` we'll return an object instance for
76
- * progressive hashing.
77
- *
78
- * If this is an `object`, we'll return an object instance, and
79
- * this will be passed as the options to the `algo.create()` method.
80
- *
81
- * If this is `false` (default), we'll return a hashing function.
82
- *
83
- * @returns {(function|object)} Output depends on parameters.
84
- */
85
- exports.hash = function(name, instance=false)
86
- {
87
- if (instance)
88
- { // Return a progressive instance.
89
- const algo = load.algo(name);
90
- const opts = isObj(instance) ? instance : {};
91
- return algo.create(opts);
92
- }
93
- else
94
- { // Return a hashing function.
95
- return load(name.replaceAll('-', ''));
96
- }
97
- }
98
-
99
- /**
100
- * Get a `HMAC` Hashing function or progressive instance.
101
- *
102
- * @param {string} libName - Name of the hashing algorithm to use.
103
- *
104
- * See {@link module:@lumjs/encode/crypto/load.hash} for a list.
105
- *
106
- * @param {string} [passphrase] - A secret passphrase for a hashing instance.
107
- *
108
- * If this is specified, we'll return an object instance for
109
- * progressive hashing.
110
- *
111
- * If this is **not** specified, we'll return a hashing function.
112
- *
113
- * @returns {(object|function)} Output depends on parameters.
114
- */
115
- exports.hmac = function(libName, passphrase)
116
- {
117
- if (typeof passphrase === S)
118
- { // Return a progressive instance.
119
- const algo = load.algo(libName);
120
- const hmac = load.algo('HMAC');
121
- return hmac.create(algo, passphrase);
122
- }
123
- else
124
- { // Return a hashing function.
125
- return load('hmac-'+libName.replaceAll('-', ''));
126
- }
127
- }
128
-
129
- const Ciphers =
130
- {
131
- rc4drop()
132
- {
133
- load('rc4', false);
134
- return cc.RC4Drop;
135
- },
136
- des()
137
- {
138
- load('tripledes', false);
139
- return cc.DES;
140
- }
141
- }
142
-
143
- /**
144
- * Get a cipher transcoder.
145
- *
146
- * @param {string} name - The name of the algorithm.
147
- *
148
- * Cipher algorithms supported by `crypto-js`:
149
- *
150
- * - AES
151
- * - DES
152
- * - TripleDES
153
- * - Rabbit
154
- * - RabbitLegacy
155
- * - RC4
156
- * - RC4Drop
157
- *
158
- * The parameter is case-insensitive.
159
- *
160
- * @returns {function} The hashing function.
161
- */
162
- exports.cipher = function(name)
163
- {
164
- name = name.replaceAll('-', '').toLowerCase();
165
- if (typeof Ciphers[name] === F)
166
- { // A custom loader function.
167
- return Ciphers[name]();
168
- }
169
- return load(name, false);
170
- }
171
-
172
- const Algos =
173
- {
174
- RC4DROP()
175
- {
176
- load('rc4', false);
177
- return cc.algo.RC4Drop;
178
- },
179
- des()
180
- {
181
- load('tripledes', false);
182
- return cc.algo.DES;
183
- },
184
- TRIPLEDES: 'TripleDES',
185
- RABBIT: 'Rabbit',
186
- RABBITLEGACY()
187
- {
188
- load('rabbit-legacy', false);
189
- return cc.algo.RabbitLegacy;
190
- },
191
- }
192
-
193
- /**
194
- * Get an algorithm plugin.
195
- *
196
- * @param {string} name - The name of the algorithm
197
- *
198
- * It can be any algorithm supported by either
199
- * the [hash()]{@link module:@lumjs/encode/crypto.hash}
200
- * or [cipher()]{@link module:@lumjs/encode/crypto.cipher}
201
- * as well as standalone algorithms like `PBKDF2`, `HMAC`, `EvpKDF`, etc.
202
- *
203
- * @returns {object} The algorithm plugin.
204
- *
205
- * You'll need to use the `create()` method on the plugin to get
206
- * an instance before you can start hashing.
207
- *
208
- */
209
- exports.algo = function(name)
210
- {
211
- name = name.replaceAll('-','').toUpperCase();
212
-
213
- if (typeof Algos[name] === F)
214
- { // A custom loader.
215
- return Algos[name]();
216
- }
217
- else if (typeof Algos[name] === S)
218
- { // A specific case-sensitive spelling.
219
- name = Algos[name];
220
- }
221
-
222
- // We make sure the library is loaded.
223
- load(name);
224
-
225
- // Now we'll get the object out of the core.
226
- return cc.algo[name];
227
- }
228
-
229
- const Encoders =
230
- {
231
- utf16be()
232
- {
233
- load('enc-utf16', false);
234
- return cc.enc.Utf16BE;
235
- },
236
- utf16le()
237
- {
238
- load('enc-utf16', false);
239
- return cc.enc.Utf16LE;
240
- },
241
- }
242
-
243
- /**
244
- * Get an encoder plugin.
245
- *
246
- * @param {*} name - The name of the encoder.
247
- *
248
- * Encoders supported:
249
- *
250
- * - Base64
251
- * - Base64-URL
252
- * - Latin1
253
- * - Hex
254
- * - UTF-8
255
- * - UTF-16
256
- * - UTF-16LE
257
- *
258
- * You can omit the `-` characters, and the parameter is
259
- * case-insensitive.
260
- *
261
- * @returns {object} The encoder plugin.
262
- */
263
- exports.enc = function(name)
264
- {
265
- name = name.replaceAll('-','').toLowerCase();
266
-
267
- if (typeof Encoders[name] === F)
268
- { // A custom loader.
269
- return Encoders[name]();
270
- }
271
-
272
- // We make sure the library is loaded.
273
- return load('enc-'+name, false);
274
- }
275
-
276
- const Paddings =
277
- {
278
- ansix923()
279
- { // This module has a typo in it, correcting that here.
280
- load('pad-ansix923', false);
281
- return cc.pad.AnsiX923;
282
- }
283
- }
284
-
285
- /**
286
- * Get a padding plugin.
287
- *
288
- * @param {string} name - Name of the plugin.
289
- * @returns {object}
290
- */
291
- exports.pad = function(name)
292
- {
293
- name = name.replaceAll('-','').toLowerCase();
294
-
295
- if (typeof Paddings[name] === F)
296
- { // A custom loader.
297
- return Paddings[name]();
298
- }
299
-
300
- return load('pad-'+name, false);
301
- }
302
-
303
- const Modes =
304
- {
305
- CBC()
306
- { // Built-in mode, no load required.
307
- return cc.mode.CBC;
308
- },
309
- CTRGLADMAN()
310
- { // Filename fuckery.
311
- return load('mode-ctr-gladman', false);
312
- }
313
- }
314
-
315
- /**
316
- * Get a mode plugin.
317
- *
318
- * @param {string} name - Name of the plugin.
319
- * @returns {object}
320
- */
321
- exports.mode = function(name)
322
- {
323
- name = name.replaceAll('-','').toUpperCase();
324
-
325
- if (typeof Modes[name] === F)
326
- { // A custom loader.
327
- return Modes[name]();
328
- }
329
-
330
- return load('mode-'+name);
331
- }
332
-
333
- /**
334
- * Get a format plugin.
335
- *
336
- * @param {string} name - Name of the plugin.
337
- * @returns {object}
338
- */
339
- exports.format = function(name)
340
- {
341
- return load('format-'+name);
342
- }
343
-
344
- // That's all folks.
@@ -1,40 +0,0 @@
1
- const Enum = require('@lumjs/core/enum');
2
-
3
- /**
4
- * The Safe64 version.
5
- * @alias module:@lumjs/encode/safe64.VERSION
6
- */
7
- exports.VERSION = 3;
8
-
9
- /**
10
- * An `Enum` of serialization formats.
11
- *
12
- * | Enum Name | Value | Description |
13
- * | --------- | ----- | ----------- |
14
- * | `NONE` | `0` | No serialization. Used when encoding a string or binary data. |
15
- * | `JSON` | `1` | Serialize with `JSON`. The simplest, **default** format. |
16
- * | `PHP` | `2` | PHP `serialize()` format. Can store object class information. |
17
- * | `UBJSON` | `3` | A binary JSON-like serialization format. |
18
- *
19
- * @alias module:@lumjs/encode/safe64.FORMAT
20
- */
21
- exports.FORMAT = Enum(['NONE','JSON','PHP','UBJSON']);
22
-
23
- /**
24
- * An `Enum` of serialization return types.
25
- *
26
- * | Enum Name | Value | Description |
27
- * | --------- | ----- | ----------- |
28
- * | `RAW` | `0` | Return the raw string/buffer value. |
29
- * | `ARR_OBJ` | `1` | In PHP, use an *associative array* for objects. |
30
- * | `STD_OBJ` | `2` | In PHP, use a *StdClass* instance for objects. |
31
- *
32
- * In this Javascript implementation, the `ARR_OBJ` and `STD_OBJ` formats
33
- * are treated exactly the same. The differenciation only matters in the
34
- * **PHP** implementation of Safe64.
35
- *
36
- * If the `FORMAT` is `NONE` or `PHP`, the `TYPE` is ignored entirely.
37
- *
38
- * @alias module:@lumjs/encode/safe64.TYPE
39
- */
40
- exports.TYPE = Enum(['RAW', 'ARR_OBJ', 'STD_OBJ']);
@@ -1,142 +0,0 @@
1
- const {N,S,isObj,needType} = require('@lumjs/core/types');
2
- const {VERSION,FORMAT,TYPE} = require('./common');
3
-
4
- const V = 'SV';
5
- const F = 'F';
6
- const T = 'T';
7
-
8
- const VL = 2;
9
- const FL = 1;
10
- const TL = 1;
11
-
12
- /**
13
- * Safe64 Header functions
14
- *
15
- * @module @lumjs/encode/safe64/header
16
- */
17
-
18
- /**
19
- * Convert a decimal number to a hexidecimal string.
20
- *
21
- * @param {number} number
22
- * @param {number} [len=1] Wanted string length.
23
- * @returns {string}
24
- * @alias module:@lumjs/encode/safe64/header.hex
25
- */
26
- function hex(number, len=0)
27
- {
28
- needType(N, number);
29
- let hex = number.toString(16);
30
- return (len > 1 ? hex.padStart(len, '0') : hex);
31
- }
32
-
33
- exports.hex = hex;
34
-
35
- /**
36
- * Convert a hex string to a decimal number.
37
- *
38
- * @param {string} hex
39
- * @returns {number}
40
- * @alias module:@lumjs/encode/safe64/header.dec
41
- */
42
- function dec(hex)
43
- {
44
- return parseInt(hex, 16);
45
- }
46
-
47
- exports.dec = dec;
48
-
49
- /**
50
- * Build a Safe64 `v3` header to be prepended to a string.
51
- *
52
- * @param {number} format
53
- * @param {number} type
54
- * @param {number} [ver=3]
55
- * @param {boolean} [full=false]
56
- * @returns {string}
57
- * @alias module:@lumjs/encode/safe64/header.build
58
- */
59
- exports.build = function(format, type, ver=VERSION, full=false)
60
- {
61
- needType(N, format, 'format must be a number');
62
- needType(N, type, 'type must be a number');
63
-
64
- let h = V + hex(ver, VL);
65
-
66
- if (full || format !== FORMAT.NONE)
67
- { // Include a format field.
68
- h += F + hex(format, FL);
69
- if (full || (type !== TYPE.RAW && format !== FORMAT.PHP))
70
- { // Include a type field.
71
- h += T + hex(type, TL);
72
- }
73
- }
74
-
75
- return h;
76
- }
77
-
78
- /**
79
- * Parse a string, looking for a `v3` header.
80
- *
81
- * @param {string} str - The string to parse.
82
- * @param {module:@lumjs/encode/safe64~Settings} [settings] Internal use only.
83
- * @returns {module:@lumjs/encode/safe64~Settings} Settings for the header.
84
- *
85
- * The settings will have a version of `0` if no header was found in the string.
86
- *
87
- * @alias module:@lumjs/encode/safe64/header.parse
88
- */
89
- exports.parse = function(str, settings)
90
- {
91
- needType(S, str);
92
-
93
- if (!isObj(settings))
94
- {
95
- settings = new Settings(FORMAT.NONE, TYPE.RAW);
96
- }
97
-
98
- let a = 0;
99
- let b = V.length;
100
-
101
- if (str.substring(a, b) === V)
102
- { // A version marker was found, continue parsing.
103
- a = b;
104
- b = a + VL;
105
- settings.version = str.substring(a, b);
106
-
107
- a = b;
108
- b = a + F.length;
109
- if (str.substring(a, b) === F)
110
- { // A format tag was found.
111
- a = b;
112
- b = a + FL;
113
- settings.format = dec(str.substring(a, b));
114
-
115
- a = b;
116
- b = a + T.length;
117
- if (str.substring(a, b) === T)
118
- { // A type tag was found.
119
- a = b;
120
- b = a + TL;
121
- settings.type = dec(str.substring(a, b));
122
- a = b;
123
- }
124
- }
125
- else
126
- { // No format header means no serialization.
127
- settings.format = FORMAT.NONE;
128
- }
129
- }
130
-
131
- // Okay, now set the string, and if applicable, offset.
132
- settings.setValue(str, a);
133
-
134
- return settings;
135
- }
136
-
137
- // Exporting for internal use.
138
- exports.V = V;
139
- exports.VL = VL;
140
-
141
- // The Settings object.
142
- const Settings = require('./settings');