@vex-chat/crypto 0.7.18 → 0.8.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.
Files changed (37) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/README.md +8 -5
  4. package/RELEASING.md +85 -0
  5. package/dist/index.d.ts +13 -7
  6. package/dist/index.js +125 -87
  7. package/jest.config.js +14 -11
  8. package/mise.toml +3 -0
  9. package/package.json +60 -58
  10. package/dist/__tests__/XKeyConvert.d.ts +0 -1
  11. package/dist/__tests__/XKeyConvert.js +0 -51
  12. package/dist/__tests__/XUtils/bytesEqual.d.ts +0 -1
  13. package/dist/__tests__/XUtils/bytesEqual.js +0 -13
  14. package/dist/__tests__/XUtils/emptyHeader.d.ts +0 -1
  15. package/dist/__tests__/XUtils/emptyHeader.js +0 -10
  16. package/dist/__tests__/XUtils/keyFileFunctions.d.ts +0 -1
  17. package/dist/__tests__/XUtils/keyFileFunctions.js +0 -18
  18. package/dist/__tests__/XUtils/numberToUint8Arr.d.ts +0 -1
  19. package/dist/__tests__/XUtils/numberToUint8Arr.js +0 -29
  20. package/dist/__tests__/XUtils/packMessage.d.ts +0 -1
  21. package/dist/__tests__/XUtils/packMessage.js +0 -16
  22. package/dist/__tests__/XUtils/stringEncoding.d.ts +0 -1
  23. package/dist/__tests__/XUtils/stringEncoding.js +0 -57
  24. package/dist/__tests__/XUtils/uint8ArrToNumber.d.ts +0 -1
  25. package/dist/__tests__/XUtils/uint8ArrToNumber.js +0 -28
  26. package/dist/__tests__/XUtils/unpackMessage.d.ts +0 -1
  27. package/dist/__tests__/XUtils/unpackMessage.js +0 -24
  28. package/dist/__tests__/xConcat.d.ts +0 -1
  29. package/dist/__tests__/xConcat.js +0 -11
  30. package/dist/__tests__/xDH.d.ts +0 -1
  31. package/dist/__tests__/xDH.js +0 -10
  32. package/dist/__tests__/xEncode.d.ts +0 -1
  33. package/dist/__tests__/xEncode.js +0 -9
  34. package/dist/__tests__/xHMAC.d.ts +0 -1
  35. package/dist/__tests__/xHMAC.js +0 -12
  36. package/dist/__tests__/xMnemonic.d.ts +0 -1
  37. package/dist/__tests__/xMnemonic.js +0 -9
@@ -0,0 +1,8 @@
1
+ # Changesets
2
+
3
+ Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
+ with multi-package repos, or single-package repos to help you version and publish your code. You can
5
+ find the full documentation for it [in the changesets repo](https://github.com/changesets/changesets)
6
+
7
+ We have a quick list of common questions to get you started engaging with this project in
8
+ [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
3
+ "changelog": "@changesets/cli/changelog",
4
+ "commit": false,
5
+ "fixed": [],
6
+ "linked": [],
7
+ "access": "public",
8
+ "baseBranch": "master",
9
+ "updateInternalDependencies": "patch",
10
+ "ignore": []
11
+ }
package/README.md CHANGED
@@ -8,8 +8,11 @@ All of the crypto functions for the key exchange are contained in here.
8
8
 
9
9
  ## external crypto dependencies
10
10
 
11
- - tweetnacl-js: sign / encrypt / decrypt / hash
12
- - create-hmac: hmac generation
13
- - ed2curve: convert ed25519 PK to x25519
14
- - bip39: mnemonic generation
15
- - futoin-hkdf: key derivation function
11
+ This library utilizes native Node.js crypto where possible for performance and security.
12
+
13
+ - **tweetnacl**: Primitives for signing and encryption (X25519 / Ed25519).
14
+ - **ed2curve**: Ed25519 signing key to X25519 encryption key conversion.
15
+ - **msgpackr**: High-performance MessagePack serialization (replacing `msgpack-lite`).
16
+ - **bip39**: Mnemonic generation for keys.
17
+ - **Node Crypto**: Native implementations for HKDF, PBKDF2, HMAC, and SHA hashing (replacing `futoin-hkdf`, `create-hmac`, and `sha.js`).
18
+ - **@stablelib**: Constant-time encoding for Base64 and UTF8.
package/RELEASING.md ADDED
@@ -0,0 +1,85 @@
1
+ # Releasing @vex-chat/crypto
2
+
3
+ This repo uses [Changesets](https://github.com/changesets/changesets) for versioning and publishing.
4
+
5
+ ## Dependency Chain
6
+
7
+ ```
8
+ @vex-chat/types
9
+ └─ @vex-chat/crypto ← you are here
10
+ └─ @vex-chat/libvex
11
+ └─ vex-desktop
12
+ ```
13
+
14
+ **Publish types first** if it has changes, then publish crypto.
15
+
16
+ ## Day-to-Day Workflow
17
+
18
+ ### 1. Work on a feature branch
19
+
20
+ ```bash
21
+ git checkout -b my-feature
22
+ # ... make changes ...
23
+ ```
24
+
25
+ ### 2. Add a changeset before pushing
26
+
27
+ ```bash
28
+ npx changeset
29
+ ```
30
+
31
+ This prompts you to:
32
+ - Select the package (`@vex-chat/crypto`)
33
+ - Choose bump type (patch / minor / major)
34
+ - Write a short summary of the change
35
+
36
+ It creates a file in `.changeset/` — commit it with your code.
37
+
38
+ ### 3. Push and open a PR
39
+
40
+ ```bash
41
+ git add .
42
+ git commit -m "my feature"
43
+ git push -u origin my-feature
44
+ ```
45
+
46
+ ### 4. Merge to master
47
+
48
+ After merge, the **Release** GitHub Action will:
49
+ 1. Detect pending changesets
50
+ 2. Open a **"chore: version packages"** PR with bumped version + updated CHANGELOG.md
51
+ 3. When you merge that PR, it publishes to npm automatically
52
+
53
+ ```
54
+
55
+ ## Release Candidates
56
+
57
+ ```bash
58
+ npx changeset pre enter rc # enter RC mode
59
+ npx changeset version # produces e.g. 0.9.0-rc.0
60
+ npx changeset publish # publishes with --tag rc
61
+
62
+ # ... more changes + changesets ...
63
+ npx changeset version # produces 0.9.0-rc.1
64
+ npx changeset publish
65
+
66
+ # ready for stable:
67
+ npx changeset pre exit
68
+ npx changeset version # produces 0.9.0
69
+ npx changeset publish # publishes as @latest
70
+ ```
71
+
72
+ ## GitHub Secrets Required
73
+
74
+ - `NPM_TOKEN` — npm access token with publish permission for `@vex-chat` scope
75
+ - `GITHUB_TOKEN` — provided automatically by GitHub Actions
76
+
77
+ ## Local Development
78
+
79
+ You can still use `yalc` for local cross-repo development:
80
+
81
+ ```bash
82
+ yarn push # builds and pushes to yalc for local consumers
83
+ ```
84
+
85
+ When publishing for real, changesets handles versioning — yalc is just for local dev loops.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- /// <reference types="node" />
2
1
  import { decode as decodeBase64, encode as encodeBase64 } from "@stablelib/base64";
3
2
  import { decode as encodeUTF8, encode as decodeUTF8 } from "@stablelib/utf8";
4
- import { XTypes } from "@vex-chat/types";
3
+ import { IBaseMsg } from "@vex-chat/types";
5
4
  import ed2curve from "ed2curve";
6
5
  /**
7
6
  * Provides an interface that can map an ed25519 keypair to its equivalent
@@ -49,20 +48,20 @@ export declare class XUtils {
49
48
  * @param arr The array to convert.
50
49
  * @returns [32 byte header, message body]
51
50
  */
52
- static unpackMessage(msg: Uint8Array | Buffer): [Uint8Array, XTypes.WS.IBaseMsg];
51
+ static unpackMessage(msg: Uint8Array | Buffer): [Uint8Array, IBaseMsg];
53
52
  /**
54
53
  * Packs a javascript object and a 32 byte header into a vex message.
55
54
  *
56
55
  * @param arr The array to convert.
57
56
  * @returns the packed message.
58
57
  */
59
- static packMessage(msg: any, header?: Uint8Array): Uint8Array;
58
+ static packMessage(msg: any, header?: Uint8Array): Uint8Array<ArrayBufferLike>;
60
59
  /**
61
60
  * Returns the empty header (32 0's)
62
61
  *
63
62
  * @returns The empty header.
64
63
  */
65
- static emptyHeader(): Uint8Array;
64
+ static emptyHeader(): Uint8Array<ArrayBuffer>;
66
65
  /**
67
66
  * Encrypts a secret key with a password and saves it as a file.
68
67
  *
@@ -72,7 +71,7 @@ export declare class XUtils {
72
71
  * @param iterationOverride An optional override if you'd prefer to manually
73
72
  * select your iterations rather than having a random amount selected.
74
73
  */
75
- static saveKeyFile: (path: string, password: string, keyToSave: string, iterationOverride?: number | undefined) => void;
74
+ static saveKeyFile: (path: string, password: string, keyToSave: string, iterationOverride?: number) => void;
76
75
  /**
77
76
  * Decrypts and returns a secret key stored in a file with saveKeyFile().
78
77
  *
@@ -106,7 +105,7 @@ export declare function xMnemonic(entropy: Uint8Array, wordList?: string[] | und
106
105
  * @param msg the message to create the HMAC of
107
106
  * @param SK the secret key to create the HMAC with
108
107
  */
109
- export declare function xHMAC(msg: any, SK: Uint8Array): Uint8Array;
108
+ export declare function xHMAC(msg: any, SK: Uint8Array): Uint8Array<ArrayBuffer>;
110
109
  /**
111
110
  * Constants for vex.
112
111
  */
@@ -122,6 +121,13 @@ export declare function xMakeNonce(): Uint8Array;
122
121
  * @returns The generated key.
123
122
  */
124
123
  export declare function xKDF(IKM: Uint8Array): Uint8Array;
124
+ /**
125
+ * Hashes some data.
126
+ *
127
+ * @param data the data to hash.
128
+ * @returns The hash of the data.
129
+ */
130
+ export declare function xHash(data: Uint8Array): string;
125
131
  /**
126
132
  * Derives a shared Secret Key from a known private key and
127
133
  * a peer's known public key.
package/dist/index.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -11,28 +15,49 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
11
15
  }) : function(o, v) {
12
16
  o["default"] = v;
13
17
  });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
21
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
22
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
37
  };
24
38
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.xEncode = exports.xConcat = exports.xDH = exports.xKDF = exports.xMakeNonce = exports.xConstants = exports.xHMAC = exports.xMnemonic = exports.XUtils = exports.XKeyConvert = void 0;
39
+ exports.xConstants = exports.XUtils = exports.XKeyConvert = void 0;
40
+ exports.xMnemonic = xMnemonic;
41
+ exports.xHMAC = xHMAC;
42
+ exports.xMakeNonce = xMakeNonce;
43
+ exports.xKDF = xKDF;
44
+ exports.xHash = xHash;
45
+ exports.xDH = xDH;
46
+ exports.xConcat = xConcat;
47
+ exports.xEncode = xEncode;
26
48
  const base64_1 = require("@stablelib/base64");
27
49
  const utf8_1 = require("@stablelib/utf8");
28
50
  const bip39 = __importStar(require("bip39"));
29
- const create_hmac_1 = __importDefault(require("create-hmac"));
51
+ const node_crypto_1 = require("node:crypto");
30
52
  const ed2curve_1 = __importDefault(require("ed2curve"));
31
53
  const fs_1 = __importDefault(require("fs"));
32
- const futoin_hkdf_1 = __importDefault(require("futoin-hkdf"));
33
- const msgpack_lite_1 = __importDefault(require("msgpack-lite"));
34
- const pbkdf2_1 = require("pbkdf2");
54
+ const node_crypto_2 = require("node:crypto");
55
+ const msgpackr_1 = require("msgpackr");
35
56
  const tweetnacl_1 = __importDefault(require("tweetnacl"));
57
+ const packer = new msgpackr_1.Packr({
58
+ useRecords: false,
59
+ moreTypes: true,
60
+ });
36
61
  /**
37
62
  * Provides an interface that can map an ed25519 keypair to its equivalent
38
63
  * X25519 keypair.
@@ -43,6 +68,10 @@ exports.XKeyConvert = ed2curve_1.default;
43
68
  * vex messages.
44
69
  */
45
70
  class XUtils {
71
+ static encodeUTF8 = utf8_1.decode;
72
+ static decodeUTF8 = utf8_1.encode;
73
+ static encodeBase64 = base64_1.encode;
74
+ static decodeBase64 = base64_1.decode;
46
75
  /**
47
76
  * Checks if two buffer-like objects are equal.
48
77
  *
@@ -101,7 +130,8 @@ class XUtils {
101
130
  static unpackMessage(msg) {
102
131
  const msgp = Uint8Array.from(msg);
103
132
  const msgh = msgp.slice(0, exports.xConstants.HEADER_SIZE);
104
- const msgb = msgpack_lite_1.default.decode(msgp.slice(exports.xConstants.HEADER_SIZE));
133
+ // UPDATED: Use msgpackr
134
+ const msgb = packer.unpack(msgp.slice(exports.xConstants.HEADER_SIZE));
105
135
  return [msgh, msgb];
106
136
  }
107
137
  /**
@@ -111,7 +141,8 @@ class XUtils {
111
141
  * @returns the packed message.
112
142
  */
113
143
  static packMessage(msg, header) {
114
- const msgb = Uint8Array.from(msgpack_lite_1.default.encode(msg));
144
+ // UPDATED: Use msgpackr
145
+ const msgb = packer.pack(msg);
115
146
  const msgh = header || XUtils.emptyHeader();
116
147
  return xConcat(msgh, msgb);
117
148
  }
@@ -123,6 +154,63 @@ class XUtils {
123
154
  static emptyHeader() {
124
155
  return new Uint8Array(exports.xConstants.HEADER_SIZE);
125
156
  }
157
+ /**
158
+ * Encrypts a secret key with a password and saves it as a file.
159
+ *
160
+ * @param path The path to save the keyfile.
161
+ * @param password The password to encrypt the keyfile with.
162
+ * @param keyToSave The key to encrypt.
163
+ * @param iterationOverride An optional override if you'd prefer to manually
164
+ * select your iterations rather than having a random amount selected.
165
+ */
166
+ static saveKeyFile = (path, password, keyToSave, iterationOverride) => {
167
+ const UNENCRYPTED_SIGNKEY = XUtils.decodeHex(keyToSave);
168
+ const OFFSET = 1000;
169
+ // generate random amount of iterations using Native Crypto
170
+ const rand = (0, node_crypto_1.randomBytes)(2);
171
+ const N1 = rand[0];
172
+ const N2 = rand[1];
173
+ const iterations = iterationOverride ? iterationOverride : N1 * N2 + OFFSET;
174
+ const ITERATIONS = XUtils.numberToUint8Arr(iterations);
175
+ const PKBDF_SALT = xMakeNonce();
176
+ const ENCRYPTION_KEY = (0, node_crypto_1.pbkdf2Sync)(password, PKBDF_SALT, iterations, 32, "sha512");
177
+ const NONCE = xMakeNonce();
178
+ const ENCRYPTED_SIGNKEY = tweetnacl_1.default.secretbox(UNENCRYPTED_SIGNKEY, NONCE, new Uint8Array(ENCRYPTION_KEY));
179
+ const result = new Uint8Array(ITERATIONS.length +
180
+ PKBDF_SALT.length +
181
+ NONCE.length +
182
+ ENCRYPTED_SIGNKEY.length);
183
+ let offset = 0;
184
+ result.set(ITERATIONS, offset);
185
+ offset += ITERATIONS.length;
186
+ result.set(PKBDF_SALT, offset);
187
+ offset += PKBDF_SALT.length;
188
+ result.set(NONCE, offset);
189
+ offset += NONCE.length;
190
+ result.set(ENCRYPTED_SIGNKEY, offset);
191
+ fs_1.default.writeFileSync(path, result);
192
+ };
193
+ /**
194
+ * Decrypts and returns a secret key stored in a file with saveKeyFile().
195
+ *
196
+ * @param path The path of the file.
197
+ * @param password The password the file was encrypted with.
198
+ */
199
+ static loadKeyFile = (path, password) => {
200
+ const keyFile = Uint8Array.from(fs_1.default.readFileSync(path));
201
+ const ITERATIONS = XUtils.uint8ArrToNumber(keyFile.slice(0, 6));
202
+ const PKBDF_SALT = keyFile.slice(6, 30);
203
+ const ENCRYPTION_NONCE = keyFile.slice(30, 54);
204
+ const ENCRYPTED_KEY = keyFile.slice(54);
205
+ const DERIVED_KEY = (0, node_crypto_1.pbkdf2Sync)(password, PKBDF_SALT, ITERATIONS, 32, "sha512");
206
+ const DECRYPTED_SIGNKEY = tweetnacl_1.default.secretbox.open(ENCRYPTED_KEY, ENCRYPTION_NONCE, new Uint8Array(DERIVED_KEY));
207
+ if (!DECRYPTED_SIGNKEY) {
208
+ throw new Error("Decryption failed. Wrong password?");
209
+ }
210
+ else {
211
+ return XUtils.encodeHex(DECRYPTED_SIGNKEY);
212
+ }
213
+ };
126
214
  /**
127
215
  * Decodes a hex string into a Uint8Array.
128
216
  *
@@ -144,63 +232,6 @@ class XUtils {
144
232
  }
145
233
  }
146
234
  exports.XUtils = XUtils;
147
- XUtils.encodeUTF8 = utf8_1.decode;
148
- XUtils.decodeUTF8 = utf8_1.encode;
149
- XUtils.encodeBase64 = base64_1.encode;
150
- XUtils.decodeBase64 = base64_1.decode;
151
- /**
152
- * Encrypts a secret key with a password and saves it as a file.
153
- *
154
- * @param path The path to save the keyfile.
155
- * @param password The password to encrypt the keyfile with.
156
- * @param keyToSave The key to encrypt.
157
- * @param iterationOverride An optional override if you'd prefer to manually
158
- * select your iterations rather than having a random amount selected.
159
- */
160
- XUtils.saveKeyFile = (path, password, keyToSave, iterationOverride) => {
161
- const UNENCRYPTED_SIGNKEY = XUtils.decodeHex(keyToSave);
162
- const OFFSET = 1000;
163
- // generate random amount of iterations
164
- const R1 = tweetnacl_1.default.randomBytes(1);
165
- const R2 = tweetnacl_1.default.randomBytes(1);
166
- const N1 = XUtils.uint8ArrToNumber(R1);
167
- const N2 = XUtils.uint8ArrToNumber(R2);
168
- const iterations = iterationOverride
169
- ? iterationOverride
170
- : N1 * N2 + OFFSET;
171
- // length 6
172
- const ITERATIONS = XUtils.numberToUint8Arr(iterations);
173
- // length 24
174
- const PKBDF_SALT = xMakeNonce();
175
- // derived key to encrypt our signkeys with
176
- const ENCRYPTION_KEY = Uint8Array.from(pbkdf2_1.pbkdf2Sync(password, PKBDF_SALT, iterations, 32));
177
- const NONCE = xMakeNonce();
178
- const ENCRYPTED_SIGNKEY = tweetnacl_1.default.secretbox(UNENCRYPTED_SIGNKEY, NONCE, ENCRYPTION_KEY);
179
- fs_1.default.writeFileSync(path, xConcat(ITERATIONS, PKBDF_SALT, NONCE, ENCRYPTED_SIGNKEY));
180
- };
181
- /**
182
- * Decrypts and returns a secret key stored in a file with saveKeyFile().
183
- *
184
- * @param path The path of the file.
185
- * @param password The password the file was encrypted with.
186
- */
187
- XUtils.loadKeyFile = (path, password) => {
188
- const keyFile = Uint8Array.from(fs_1.default.readFileSync(path));
189
- const ITERATIONS = XUtils.uint8ArrToNumber(keyFile.slice(0, 6));
190
- const PKBDF_SALT = keyFile.slice(6, 30);
191
- const ENCRYPTION_NONCE = keyFile.slice(30, 54);
192
- // this is the id key we need to decrypt
193
- const ENCRYPTED_KEY = keyFile.slice(54);
194
- // the derived key from the user's password
195
- const DERIVED_KEY = Uint8Array.from(pbkdf2_1.pbkdf2Sync(password, PKBDF_SALT, ITERATIONS, 32));
196
- const DECRYPTED_SIGNKEY = tweetnacl_1.default.secretbox.open(ENCRYPTED_KEY, ENCRYPTION_NONCE, DERIVED_KEY);
197
- if (!DECRYPTED_SIGNKEY) {
198
- throw new Error("Decryption failed. Wrong password?");
199
- }
200
- else {
201
- return XUtils.encodeHex(DECRYPTED_SIGNKEY);
202
- }
203
- };
204
235
  /**
205
236
  * Gets a word list representation of a byte sequence.
206
237
  *
@@ -210,7 +241,6 @@ XUtils.loadKeyFile = (path, password) => {
210
241
  function xMnemonic(entropy, wordList) {
211
242
  return bip39.entropyToMnemonic(Buffer.from(entropy), wordList);
212
243
  }
213
- exports.xMnemonic = xMnemonic;
214
244
  /**
215
245
  * Returns a 32 byte HMAC of a javscript object.
216
246
  *
@@ -218,13 +248,12 @@ exports.xMnemonic = xMnemonic;
218
248
  * @param SK the secret key to create the HMAC with
219
249
  */
220
250
  function xHMAC(msg, SK) {
221
- const packedMsg = Uint8Array.from(msgpack_lite_1.default.encode(msg));
222
- const hmacGen = create_hmac_1.default("sha256", Buffer.from(SK));
251
+ const packedMsg = packer.pack(msg);
252
+ const hmacGen = (0, node_crypto_1.createHmac)("sha256", Buffer.from(SK));
223
253
  hmacGen.update(packedMsg);
224
254
  const hmac = Uint8Array.from(hmacGen.digest());
225
255
  return hmac;
226
256
  }
227
- exports.xHMAC = xHMAC;
228
257
  /**
229
258
  * Constants for vex.
230
259
  */
@@ -242,21 +271,34 @@ exports.xConstants = {
242
271
  function xMakeNonce() {
243
272
  return tweetnacl_1.default.randomBytes(24);
244
273
  }
245
- exports.xMakeNonce = xMakeNonce;
246
274
  /**
247
275
  * Derives a 32 byte secret key from some initial key material.
248
276
  *
249
277
  * @param IKM the initial key material.
250
278
  * @returns The generated key.
251
279
  */
280
+ // export function xKDF(IKM: Uint8Array): Uint8Array {
281
+ // return Uint8Array.from(
282
+ // hkdf(Buffer.from(IKM), xConstants.KEY_LENGTH, {
283
+ // salt: Buffer.from(xMakeSalt(xConstants.CURVE)),
284
+ // info: xConstants.INFO,
285
+ // hash: xConstants.HASH,
286
+ // })
287
+ // );
288
+ // }
252
289
  function xKDF(IKM) {
253
- return Uint8Array.from(futoin_hkdf_1.default(Buffer.from(IKM), exports.xConstants.KEY_LENGTH, {
254
- salt: Buffer.from(xMakeSalt(exports.xConstants.CURVE)),
255
- info: exports.xConstants.INFO,
256
- hash: exports.xConstants.HASH,
257
- }));
290
+ return new Uint8Array((0, node_crypto_2.hkdfSync)("sha512", IKM, xMakeSalt(exports.xConstants.CURVE), exports.xConstants.INFO, exports.xConstants.KEY_LENGTH));
291
+ }
292
+ /**
293
+ * Hashes some data.
294
+ *
295
+ * @param data the data to hash.
296
+ * @returns The hash of the data.
297
+ */
298
+ function xHash(data) {
299
+ const hash = (0, node_crypto_1.createHash)("sha512");
300
+ return hash.update(data).digest("hex");
258
301
  }
259
- exports.xKDF = xKDF;
260
302
  /**
261
303
  * Derives a shared Secret Key from a known private key and
262
304
  * a peer's known public key.
@@ -268,14 +310,12 @@ exports.xKDF = xKDF;
268
310
  function xDH(myPrivateKey, theirPublicKey) {
269
311
  return tweetnacl_1.default.box.before(theirPublicKey, myPrivateKey);
270
312
  }
271
- exports.xDH = xDH;
272
313
  /**
273
314
  * Concatanates multiple Uint8Arrays.
274
315
  *
275
316
  * @param arrays As many Uint8Arrays as you would like to concatanate.
276
317
  */
277
318
  function xConcat(...arrays) {
278
- // sum of individual array lengths
279
319
  const totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
280
320
  if (!arrays.length) {
281
321
  return new Uint8Array();
@@ -290,7 +330,6 @@ function xConcat(...arrays) {
290
330
  }
291
331
  return result;
292
332
  }
293
- exports.xConcat = xConcat;
294
333
  /**
295
334
  * Encode an X25519 or X448 public key PK into a byte sequence.
296
335
  * The encoding consists of 0 or 1 to represent the type of curve, followed by l
@@ -324,7 +363,6 @@ function xEncode(curveType, publicKey) {
324
363
  }
325
364
  return Uint8Array.from(bytes);
326
365
  }
327
- exports.xEncode = xEncode;
328
366
  /**
329
367
  * @ignore
330
368
  */
package/jest.config.js CHANGED
@@ -1,13 +1,16 @@
1
- // TODO: convert to es6 format
2
1
  module.exports = {
3
- "roots": [
4
- "<rootDir>/src"
2
+ roots: ["<rootDir>/src"],
3
+ testMatch: [
4
+ "**/__tests__/**/*.+(ts|tsx|js)",
5
+ "**/?(*.)+(spec|test).+(ts|tsx|js)",
6
+ ],
7
+ transform: {
8
+ "^.+\\.(ts|tsx)$": [
9
+ "ts-jest",
10
+ {
11
+ diagnostics: false,
12
+ isolatedModules: true,
13
+ },
5
14
  ],
6
- "testMatch": [
7
- "**/__tests__/**/*.+(ts|tsx|js)",
8
- "**/?(*.)+(spec|test).+(ts|tsx|js)"
9
- ],
10
- "transform": {
11
- "^.+\\.(ts|tsx)$": "ts-jest"
12
- },
13
- }
15
+ },
16
+ };
package/mise.toml ADDED
@@ -0,0 +1,3 @@
1
+ [tools]
2
+ node = "20"
3
+ "npm:yarn" = "latest"
package/package.json CHANGED
@@ -1,60 +1,62 @@
1
1
  {
2
- "name": "@vex-chat/crypto",
3
- "version": "0.7.18",
4
- "description": "Crypto functions for vex",
5
- "main": "./dist/index.js",
6
- "author": "Extra <extrahash@protonmail.com>",
7
- "license": "AGPL-3.0-or-later",
8
- "scripts": {
9
- "start": "node ./dist/index.js",
10
- "build": "rm -rf ./dist/*; node ./node_modules/typescript/bin/tsc",
11
- "prepack": "yarn build",
12
- "prettier": "node ./node_modules/prettier/bin-prettier.js '**/*.{ts,tsx,json,md}' --tab-width 4 --trailing-comma es5 --ignore-path .gitignore --arrow-parens always --write",
13
- "lint": "./node_modules/tslint/bin/tslint src/**/*.ts{,x}",
14
- "lint-fix": "./node_modules/tslint/bin/tslint src/**/*.ts{,x} --fix",
15
- "test": "npx jest",
16
- "docs": "npx typedoc"
17
- },
18
- "devDependencies": {
19
- "@types/lodash": "^4.14.166",
20
- "@types/uuid": "^8.3.0",
21
- "husky": "^3.1.0",
22
- "jest": "^26.6.3",
23
- "lint-staged": "^9.5.0",
24
- "lodash": "^4.17.20",
25
- "prettier": "^1.19.1",
26
- "ts-jest": "^26.4.4",
27
- "tslint": "^5.20.1",
28
- "tslint-config-prettier": "^1.18.0",
29
- "typedoc": "^0.19.2",
30
- "typedoc-plugin-no-inherit": "^1.2.0",
31
- "typescript": "^3.7.2"
32
- },
33
- "lint-staged": {
34
- "src/**/*.{ts}": [
35
- "./node_modules/tslint/bin/tslint -c tslint.json --fix",
36
- "git add"
37
- ]
38
- },
39
- "husky": {
40
- "hooks": {
41
- "pre-commit": "yarn prettier; git add --all; lint-staged"
42
- }
43
- },
44
- "dependencies": {
45
- "@stablelib/base64": "^1.0.0",
46
- "@stablelib/utf8": "^1.0.0",
47
- "@types/create-hmac": "^1.1.0",
48
- "@types/ed2curve": "^0.2.2",
49
- "@types/msgpack-lite": "^0.1.7",
50
- "@types/pbkdf2": "^3.1.0",
51
- "@vex-chat/types": "^0.7.21",
52
- "bip39": "^3.0.3",
53
- "create-hmac": "^1.1.7",
54
- "ed2curve": "^0.3.0",
55
- "futoin-hkdf": "^1.3.2",
56
- "msgpack-lite": "^0.1.26",
57
- "pbkdf2": "^3.1.1",
58
- "tweetnacl": "^1.0.3"
59
- }
2
+ "name": "@vex-chat/crypto",
3
+ "version": "0.8.0",
4
+ "description": "Crypto primitives for Vex",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "author": "Extra <extrahash@protonmail.com>",
8
+ "license": "AGPL-3.0-or-later",
9
+ "scripts": {
10
+ "build": "rimraf dist && tsc",
11
+ "prepack": "yarn build",
12
+ "prettier": "prettier '**/*.{ts,tsx,json,md}' --ignore-path .gitignore --write",
13
+ "lint": "eslint src/**/*.ts",
14
+ "lint-fix": "eslint src/**/*.ts --fix",
15
+ "push": "yarn build && yalc push",
16
+ "prepublish": "yarn build",
17
+ "test": "npx jest --runInBand --forceExit"
18
+ },
19
+ "dependencies": {
20
+ "@stablelib/base64": "^1.0.1",
21
+ "@stablelib/utf8": "^1.0.1",
22
+ "@vex-chat/types": "^0.11.0",
23
+ "bip39": "^3.1.0",
24
+ "ed2curve": "^0.3.0",
25
+ "msgpackr": "^1.10.1",
26
+ "tweetnacl": "^1.0.3",
27
+ "uuid": "^9.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/create-hmac": "^1.1.3",
31
+ "@types/ed2curve": "^0.2.4",
32
+ "@types/jest": "^30.0.0",
33
+ "@types/lodash": "^4.17.21",
34
+ "@types/node": "^25.0.3",
35
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
36
+ "@typescript-eslint/parser": "^8.0.0",
37
+ "eslint": "^9.0.0",
38
+ "eslint-config-prettier": "^9.0.0",
39
+ "husky": "^9.0.0",
40
+ "jest": "^30.2.0",
41
+ "lint-staged": "^15.2.0",
42
+ "lodash": "^4.17.21",
43
+ "prettier": "^3.2.0",
44
+ "rimraf": "^5.0.0",
45
+ "ts-jest": "^29.4.6",
46
+ "typescript": "^5.7.0",
47
+ "@changesets/cli": "^2.29.8"
48
+ },
49
+ "lint-staged": {
50
+ "src/**/*.{ts}": [
51
+ "eslint --fix"
52
+ ]
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/vex-chat/libvex-js.git"
57
+ },
58
+ "bugs": {
59
+ "url": "https://github.com/vex-chat/libvex-js/issues"
60
+ },
61
+ "homepage": "https://github.com/vex-chat/libvex-js#readme"
60
62
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,51 +0,0 @@
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
- // tslint:disable-next-line: no-implicit-dependencies
7
- const lodash_1 = __importDefault(require("lodash"));
8
- const __1 = require("..");
9
- const ed25519Keys = {
10
- public: "8d0538a45bce3d6fd43cd80a247da063c67cd01da2e263758567a51db5b1f7c6",
11
- private: "f69c92fbb224e1d75c5dffb5e40946e6106baa89ad73dbb6ef0bec2d8562d8a28d0538a45bce3d6fd43cd80a247da063c67cd01da2e263758567a51db5b1f7c6",
12
- };
13
- const convertedX25519Keys = {
14
- public: "55c4ca5a1d8e2859e186f36564cc41c9c9882ed9dbc01be8ec9a36b106eeee5b",
15
- private: "10ed501acc2125730c294aa4b78eac989588d031015d1c77a75ea98aa7744b7a",
16
- };
17
- test("convertKeyPair", () => {
18
- const keys = keyPairFromString(ed25519Keys);
19
- const converted = __1.XKeyConvert.convertKeyPair(keys);
20
- expect(lodash_1.default.isEqual(converted, keyPairFromString(convertedX25519Keys))).toBe(true);
21
- });
22
- test("convertPublicKey", () => {
23
- const keys = keyPairFromString(ed25519Keys);
24
- const convertedPublicKey = __1.XKeyConvert.convertPublicKey(keys.publicKey);
25
- if (!convertedPublicKey) {
26
- throw new Error("Conversion failed.");
27
- }
28
- const correctConvertedKey = __1.XUtils.decodeHex(convertedX25519Keys.public);
29
- expect(__1.XUtils.bytesEqual(convertedPublicKey, correctConvertedKey)).toBe(true);
30
- });
31
- test("convertPrivateKey", () => {
32
- const keys = keyPairFromString(ed25519Keys);
33
- const convertedPrivateKey = __1.XKeyConvert.convertSecretKey(keys.secretKey);
34
- if (!convertedPrivateKey) {
35
- throw new Error("Conversion failed.");
36
- }
37
- const correctConvertedKey = __1.XUtils.decodeHex(convertedX25519Keys.private);
38
- expect(__1.XUtils.bytesEqual(convertedPrivateKey, correctConvertedKey)).toBe(true);
39
- });
40
- function keyPairToString(keyPair) {
41
- return {
42
- public: __1.XUtils.encodeHex(keyPair.publicKey),
43
- private: __1.XUtils.encodeHex(keyPair.secretKey),
44
- };
45
- }
46
- function keyPairFromString(strKeyPair) {
47
- return {
48
- publicKey: __1.XUtils.decodeHex(strKeyPair.public),
49
- secretKey: __1.XUtils.decodeHex(strKeyPair.private),
50
- };
51
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_1 = require("../../index");
4
- const { bytesEqual } = index_1.XUtils;
5
- test("bytesEqual", () => {
6
- const bytes = [25, 23, 122, 142, 73, 92, 58];
7
- const buf1 = Buffer.from(bytes);
8
- const buf2 = Buffer.from(bytes);
9
- expect(bytesEqual(buf1, buf2)).toBe(true);
10
- bytes[0] = 0;
11
- const buf3 = Buffer.from(bytes);
12
- expect(bytesEqual(buf1, buf3)).toBe(false);
13
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,10 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_1 = require("../../index");
4
- const { emptyHeader } = index_1.XUtils;
5
- test("emptyHeader", () => {
6
- const headerData = "0000000000000000000000000000000000000000000000000000000000000000";
7
- const eHeader = emptyHeader();
8
- const testEmptyHeader = index_1.XUtils.decodeHex(headerData);
9
- expect(index_1.XUtils.bytesEqual(eHeader, testEmptyHeader)).toBe(true);
10
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,18 +0,0 @@
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
- const index_1 = require("../../index");
7
- const { saveKeyFile, loadKeyFile } = index_1.XUtils;
8
- const fs_1 = __importDefault(require("fs"));
9
- test("Save a key and reload it", () => {
10
- const secretKey = "86fbed70aa300a523979a318799d6d523a6cb4c84bfb865d3a3e52a568ec6a63560eeaae57a57d62668898355c2218b142d6069bf9f53a00b5c3c46dd257c4dc";
11
- const password = "hunter2";
12
- const fileName = "test.keyfile";
13
- saveKeyFile(fileName, password, secretKey);
14
- const decryptedKey = loadKeyFile(fileName, password);
15
- expect(secretKey === decryptedKey).toBe(true);
16
- // cleanup the file
17
- fs_1.default.unlinkSync(fileName);
18
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_1 = require("../../index");
4
- const { numberToUint8Arr, bytesEqual } = index_1.XUtils;
5
- test("numberToUint8Arr", () => {
6
- const numbers = [
7
- 255,
8
- 65535,
9
- 16777215,
10
- 4294967295,
11
- 1099511627775,
12
- 281474976710655,
13
- ];
14
- const buffers = [
15
- [0, 0, 0, 0, 0, 255],
16
- [0, 0, 0, 0, 255, 255],
17
- [0, 0, 0, 255, 255, 255],
18
- [0, 0, 255, 255, 255, 255],
19
- [0, 255, 255, 255, 255, 255],
20
- [255, 255, 255, 255, 255, 255],
21
- ];
22
- // tslint:disable-next-line: prefer-for-of
23
- for (let i = 0; i < numbers.length; i++) {
24
- const arr = numberToUint8Arr(numbers[i]);
25
- expect(bytesEqual(arr, Buffer.from(buffers[i]))).toBe(true);
26
- }
27
- expect(() => numberToUint8Arr(281474976710656)).toThrow();
28
- expect(() => numberToUint8Arr(-1)).toThrow();
29
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_1 = require("../../index");
4
- const { packMessage, emptyHeader } = index_1.XUtils;
5
- test("packMessage", () => {
6
- const testMessage = {
7
- type: "resource",
8
- resourceType: "server",
9
- action: "create",
10
- transmissionID: "8154ac29-54fb-407c-8353-0f67742bb7c4",
11
- data: "A Server Name",
12
- };
13
- const packedTestMessage = "000000000000000000000000000000000000000000000000000000000000000085a474797065a87265736f75726365ac7265736f7572636554797065a6736572766572a6616374696f6ea6637265617465ae7472616e736d697373696f6e4944d92438313534616332392d353466622d343037632d383335332d306636373734326262376334a464617461ad4120536572766572204e616d65";
14
- const packedMessage = index_1.XUtils.encodeHex(packMessage(testMessage, emptyHeader()));
15
- expect(packedTestMessage === packedMessage).toBe(true);
16
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,57 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_1 = require("../../index");
4
- const { encodeHex, decodeHex, encodeUTF8, decodeUTF8, encodeBase64, decodeBase64, } = index_1.XUtils;
5
- test("Encodes and decodes hex", () => {
6
- const data = [
7
- "a2dc693b93b3e2a31eb2b54f26f43b8ce971c6b9b4197544",
8
- "9d9158ea82750c0b164834789f216d5a17a223d87e082199",
9
- "e32079ba7c8ed5e62123ab55386689c2ec9f480ebb82f05c",
10
- "e037b3f87bea23b8afea27c7ad173f5a43d0050559fbe091",
11
- "df3cefb0f980f96eb5d6cc996702d6d166413fb2785772b1",
12
- "6a328c1b103d1b331c9759ddde6c5df5753010a3c9881514",
13
- "c5ad6470766845c420205700aaaed806456cae49b905aeed",
14
- "5dc12b62156b1f68698b36b42e3e2f4716dffee09b768030",
15
- "2985705f1f590b11e027ea6a05cbe4e0d351ab81748cbea0",
16
- "6455945ea7110197a17a809cb973c2007eff629d5549273a",
17
- ];
18
- for (const value of data) {
19
- expect(encodeHex(decodeHex(value)) === value).toBe(true);
20
- }
21
- });
22
- test("Encodes and decodes utf8", () => {
23
- const data = [
24
- "L-dr`?%z5%?R8rT:Lwvk",
25
- "H]gy!'X\")(:V/3.'LpE/",
26
- "5G%h:@%PvCOk R,[]=z>",
27
- '#d868evg)LM"{04$gFt',
28
- '?\\/sz?&mh"$!K1_`qc15',
29
- "V{Yw[ R{5L}1T3OHSj.",
30
- "%-Kek[HIfW=_z`r'R|Av",
31
- "E.E'\"\\ jzyxpfc'.N*z`",
32
- "p:&^?<[n<ScUXB#O=|z",
33
- 'D;`5`"@H7X8Iw0%KbJr8',
34
- '#,y][nQ9]",.62Bwxj#d',
35
- '[eN"USyz$Dg@%a=a)r2h',
36
- ];
37
- for (const value of data) {
38
- expect(encodeUTF8(decodeUTF8(value))).toBe(value);
39
- }
40
- });
41
- test("Encodes and decodes base64", () => {
42
- const data = [
43
- "+UMP/v5VnVF/qSrSDfcLAXZ9jEauYFrbAcgtE3z46bI=",
44
- "Cb+zq/R1zMRSEMGA1p47XWzwD48NZ/JqLO1p1hUnpEY=",
45
- "mODgEB/U3MnvMHuG5fQ0xv8NRqo24diRlzyzJ4/Et7g=",
46
- "vvYVuOpi3/pMdP49C7TgTqEdk02/LlcIY9a0CPyOJsc=",
47
- "S6vBIf8WXmPi/BPV3ei9CMgdanxBNiTl8oHQ/HSnvsU=",
48
- "0i2WNMF8I5ewIAefTbBBjhS3sZwZ9tILLpksPE00bt8=",
49
- "W3SHYUb/F3sWFytIYNG4TCBgrDT80L0A9bB335nU8/8=",
50
- "vbov+TNLyWc+VdpH7egFOifdKup26ertUlutTv8kFyY=",
51
- "re9JVfQRSsXaaUG9uLoMd/bW05xDcCnk0qaPh6CUn90=",
52
- "X9AyjBOM9tAsXrINjeDr5wgMiZNlkK5HlOOtDBwMeFw=",
53
- ];
54
- for (const value of data) {
55
- expect(encodeBase64(decodeBase64(value)) === value).toBe(true);
56
- }
57
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_1 = require("../../index");
4
- const { uint8ArrToNumber, bytesEqual } = index_1.XUtils;
5
- test("uint8ArrToNumber", () => {
6
- const numbers = [
7
- 255,
8
- 65535,
9
- 16777215,
10
- 4294967295,
11
- 1099511627775,
12
- 281474976710655,
13
- ];
14
- const buffers = [
15
- [0, 0, 0, 0, 0, 255],
16
- [0, 0, 0, 0, 255, 255],
17
- [0, 0, 0, 255, 255, 255],
18
- [0, 0, 255, 255, 255, 255],
19
- [0, 255, 255, 255, 255, 255],
20
- [255, 255, 255, 255, 255, 255],
21
- ];
22
- // tslint:disable-next-line: prefer-for-of
23
- for (let i = 0; i < numbers.length; i++) {
24
- const num1 = uint8ArrToNumber(Buffer.from(buffers[i]));
25
- const num2 = numbers[i];
26
- expect(num1 === num2).toBe(true);
27
- }
28
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,24 +0,0 @@
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
- // tslint:disable-next-line: no-implicit-dependencies
7
- const lodash_1 = __importDefault(require("lodash"));
8
- const index_1 = require("../../index");
9
- const { unpackMessage, emptyHeader, bytesEqual } = index_1.XUtils;
10
- test("packMessage", () => {
11
- const testHeader = emptyHeader();
12
- const testMessage = {
13
- type: "resource",
14
- resourceType: "server",
15
- action: "create",
16
- transmissionID: "8154ac29-54fb-407c-8353-0f67742bb7c4",
17
- data: "A Server Name",
18
- };
19
- const packedTestMessage = "000000000000000000000000000000000000000000000000000000000000000085a474797065a87265736f75726365ac7265736f7572636554797065a6736572766572a6616374696f6ea6637265617465ae7472616e736d697373696f6e4944d92438313534616332392d353466622d343037632d383335332d306636373734326262376334a464617461ad4120536572766572204e616d65";
20
- const messageData = index_1.XUtils.decodeHex(packedTestMessage);
21
- const [unpackedHeader, unpackedMessage] = unpackMessage(messageData);
22
- expect(bytesEqual(unpackedHeader, testHeader)).toBe(true);
23
- expect(lodash_1.default.isEqual(testMessage, unpackedMessage)).toBe(true);
24
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const __1 = require("..");
4
- test("xConcat", () => {
5
- const data1 = "dead";
6
- const data2 = "beef";
7
- const data3 = "bead";
8
- const correctConcatData = data1 + data2 + data3;
9
- const concatData = __1.XUtils.encodeHex(__1.xConcat(__1.XUtils.decodeHex(data1), __1.XUtils.decodeHex(data2), __1.XUtils.decodeHex(data3)));
10
- expect(concatData === correctConcatData).toBe(true);
11
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,10 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const __1 = require("..");
4
- test("xDH", () => {
5
- const myPrivateKey = "918ed243e2c6c507168b20e8b167cff33a10c30e99e8defe28dc2147f5cce703";
6
- const theirPublicKey = "6f4cc1ffc4009bd4f94628ba5922e40afa3491f0daa43ec9da0f7dc39bb1c026";
7
- const correctDerivedKey = "19a8594bdcf875ec9d4b8b9615ea8b73a0b327bb64b8f727dd2dee3a603a2230";
8
- const derivedKey = __1.XUtils.encodeHex(__1.xDH(__1.XUtils.decodeHex(myPrivateKey), __1.XUtils.decodeHex(theirPublicKey)));
9
- expect(correctDerivedKey === derivedKey).toBe(true);
10
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const __1 = require("..");
4
- test("xEncode", () => {
5
- const PK = "3a488fc006156e77e58793846c204f17e0df88e914fc7638a084524a9124bf87";
6
- const correctEncoded = "00013a488fc006156e77e58793846c204f17e0df88e914fc7638a084524a9124bf87";
7
- const encoded = __1.XUtils.encodeHex(__1.xEncode("X25519", __1.XUtils.decodeHex(PK)));
8
- expect(encoded === correctEncoded).toBe(true);
9
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const __1 = require("..");
4
- test("xHMAC", () => {
5
- const message = {
6
- hello: "world",
7
- };
8
- const SK = "b45203ef77c0a7fe7f771297f3e5c8248fe5b9f18ecf77faf8a8cef1058e630a";
9
- const correctHMAC = "a9b398cb69d356f0376c3ec78bc16aa885fdf3cd5be2203f0cc15a3340f3b0fe";
10
- const hmac = __1.XUtils.encodeHex(__1.xHMAC(message, __1.XUtils.decodeHex(SK)));
11
- expect(correctHMAC === hmac).toBe(true);
12
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const __1 = require("..");
4
- test("xMnemonic", () => {
5
- const IKM = "dfb3c08de7335cc352e2c063c8e6891a06e17bf0dfcb4eec8139fc5eaf482b0e";
6
- const correctMnemonic = "text own casino solar cupboard giant entire fix glow elbow pelican cross host sadness sell west exclude goat example weather turtle piano promote scene";
7
- const mnemonic = __1.xMnemonic(__1.XUtils.decodeHex(IKM));
8
- expect(mnemonic === correctMnemonic).toBe(true);
9
- });