@vex-chat/crypto 1.1.0-rc.1 → 2.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/README.md +75 -12
- package/dist/index.d.ts +112 -79
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +214 -165
- package/dist/index.js.map +1 -0
- package/package.json +108 -77
- package/src/__tests__/XKeyConvert.ts +68 -0
- package/src/__tests__/XUtils/bytesEqual.ts +16 -0
- package/src/__tests__/XUtils/emptyHeader.ts +12 -0
- package/src/__tests__/XUtils/numberToUint8Arr.ts +22 -0
- package/src/__tests__/XUtils/packMessage.ts +23 -0
- package/src/__tests__/XUtils/stringEncoding.ts +68 -0
- package/src/__tests__/XUtils/uint8ArrToNumber.ts +19 -0
- package/src/__tests__/XUtils/unpackMessage.ts +25 -0
- package/src/__tests__/xConcat.ts +18 -0
- package/src/__tests__/xDH.ts +16 -0
- package/src/__tests__/xEncode.ts +11 -0
- package/src/__tests__/xHMAC.ts +26 -0
- package/src/__tests__/xMnemonic.ts +12 -0
- package/src/index.ts +540 -0
package/dist/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
2
|
+
import { hmac } from "@noble/hashes/hmac.js";
|
|
3
|
+
import { pbkdf2 as noblePbkdf2 } from "@noble/hashes/pbkdf2.js";
|
|
4
|
+
import { sha256, sha512 } from "@noble/hashes/sha2.js";
|
|
1
5
|
import { decode as decodeBase64, encode as encodeBase64, } from "@stablelib/base64";
|
|
2
|
-
import {
|
|
6
|
+
import { encode as decodeUTF8, decode as encodeUTF8 } from "@stablelib/utf8";
|
|
3
7
|
import * as bip39 from "bip39";
|
|
4
|
-
import { createHash, createHmac, pbkdf2Sync, randomBytes } from "node:crypto";
|
|
5
8
|
import ed2curve from "ed2curve";
|
|
6
|
-
import { writeFileSync, readFileSync } from "node:fs";
|
|
7
|
-
import { hkdfSync } from "node:crypto";
|
|
8
9
|
import { Packr } from "msgpackr";
|
|
9
10
|
import nacl from "tweetnacl";
|
|
11
|
+
import { z } from "zod/v4";
|
|
10
12
|
// msgpackr with useRecords:false emits standard msgpack (no nonstandard record extension).
|
|
11
13
|
// moreTypes:false keeps the extension set to only what other decoders understand.
|
|
12
14
|
// pack() returns Node Buffer (tight view) so consumers like axios send the correct bytes.
|
|
13
|
-
const packer = new Packr({
|
|
15
|
+
const packer = new Packr({ moreTypes: false, useRecords: false });
|
|
14
16
|
const msgpackEncode = packer.pack.bind(packer);
|
|
15
17
|
const msgpackDecode = packer.unpack.bind(packer);
|
|
16
18
|
/**
|
|
@@ -22,11 +24,12 @@ export const XKeyConvert = ed2curve;
|
|
|
22
24
|
* Provides several methods that are useful in working with bytes and
|
|
23
25
|
* vex messages.
|
|
24
26
|
*/
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-extraneous-class -- intentional static utility namespace (public API surface)
|
|
25
28
|
export class XUtils {
|
|
26
|
-
static
|
|
29
|
+
static decodeBase64 = decodeBase64;
|
|
27
30
|
static decodeUTF8 = decodeUTF8;
|
|
28
31
|
static encodeBase64 = encodeBase64;
|
|
29
|
-
static
|
|
32
|
+
static encodeUTF8 = encodeUTF8;
|
|
30
33
|
/**
|
|
31
34
|
* Checks if two buffer-like objects are equal.
|
|
32
35
|
*
|
|
@@ -49,56 +52,40 @@ export class XUtils {
|
|
|
49
52
|
return true;
|
|
50
53
|
}
|
|
51
54
|
/**
|
|
52
|
-
*
|
|
53
|
-
* The integer must be positive, and it must be able to be stored
|
|
54
|
-
* in six bytes.
|
|
55
|
+
* Decodes a hex string into a Uint8Array.
|
|
55
56
|
*
|
|
56
|
-
* @
|
|
57
|
-
* @returns The Uint8Array representation of n.
|
|
57
|
+
* @returns The Uint8Array.
|
|
58
58
|
*/
|
|
59
|
-
static
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
let str = n.toString(16);
|
|
64
|
-
while (str.length < 12) {
|
|
65
|
-
str = "0" + str;
|
|
59
|
+
static decodeHex(hexString) {
|
|
60
|
+
if (hexString.length === 0) {
|
|
61
|
+
return new Uint8Array();
|
|
66
62
|
}
|
|
67
|
-
|
|
63
|
+
const matches = hexString.match(/.{1,2}/g) ?? [];
|
|
64
|
+
return new Uint8Array(matches.map((byte) => parseInt(byte, 16)));
|
|
68
65
|
}
|
|
69
66
|
/**
|
|
70
|
-
*
|
|
67
|
+
* Decrypts a secret key from the binary format produced by encryptKeyData().
|
|
68
|
+
* No I/O — the caller handles reading the data.
|
|
71
69
|
*
|
|
72
|
-
* @param
|
|
73
|
-
* @
|
|
70
|
+
* @param keyData The encrypted key data as a Uint8Array.
|
|
71
|
+
* @param password The password used to encrypt.
|
|
72
|
+
* @returns The hex-encoded secret key.
|
|
74
73
|
*/
|
|
75
|
-
static
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Packs a javascript object and a 32 byte header into a vex message.
|
|
93
|
-
*
|
|
94
|
-
* @param arr The array to convert.
|
|
95
|
-
* @returns the packed message.
|
|
96
|
-
*/
|
|
97
|
-
static packMessage(msg, header) {
|
|
98
|
-
const msgb = msgpackEncode(msg);
|
|
99
|
-
const msgh = header || XUtils.emptyHeader();
|
|
100
|
-
return xConcat(msgh, msgb);
|
|
101
|
-
}
|
|
74
|
+
static decryptKeyData = (keyData, password) => {
|
|
75
|
+
const ITERATIONS = XUtils.uint8ArrToNumber(keyData.slice(0, 6));
|
|
76
|
+
const PKBDF_SALT = keyData.slice(6, 30);
|
|
77
|
+
const ENCRYPTION_NONCE = keyData.slice(30, 54);
|
|
78
|
+
const ENCRYPTED_KEY = keyData.slice(54);
|
|
79
|
+
const DERIVED_KEY = noblePbkdf2(sha512, password, PKBDF_SALT, {
|
|
80
|
+
c: ITERATIONS,
|
|
81
|
+
dkLen: 32,
|
|
82
|
+
});
|
|
83
|
+
const DECRYPTED_SIGNKEY = nacl.secretbox.open(ENCRYPTED_KEY, ENCRYPTION_NONCE, DERIVED_KEY);
|
|
84
|
+
if (DECRYPTED_SIGNKEY === null) {
|
|
85
|
+
throw new Error("Decryption failed. Wrong password?");
|
|
86
|
+
}
|
|
87
|
+
return XUtils.encodeHex(DECRYPTED_SIGNKEY);
|
|
88
|
+
};
|
|
102
89
|
/**
|
|
103
90
|
* Returns the empty header (32 0's)
|
|
104
91
|
*
|
|
@@ -108,27 +95,45 @@ export class XUtils {
|
|
|
108
95
|
return new Uint8Array(xConstants.HEADER_SIZE);
|
|
109
96
|
}
|
|
110
97
|
/**
|
|
111
|
-
*
|
|
98
|
+
* Encodes a Uint8Array to a hex string.
|
|
112
99
|
*
|
|
113
|
-
* @
|
|
114
|
-
* @param password The password to encrypt the keyfile with.
|
|
115
|
-
* @param keyToSave The key to encrypt.
|
|
116
|
-
* @param iterationOverride An optional override if you'd prefer to manually
|
|
117
|
-
* select your iterations rather than having a random amount selected.
|
|
100
|
+
* @returns The hex string.
|
|
118
101
|
*/
|
|
119
|
-
static
|
|
102
|
+
static encodeHex(bytes) {
|
|
103
|
+
return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Encrypts a secret key with a password and saves it as a file.
|
|
107
|
+
*
|
|
108
|
+
* @param path The path to save the keyfile.
|
|
109
|
+
/**
|
|
110
|
+
* Encrypts a secret key into a portable binary format.
|
|
111
|
+
* The result can be written to disk, sent over the network, etc.
|
|
112
|
+
* No I/O — the caller handles persistence.
|
|
113
|
+
*
|
|
114
|
+
* Format: [iterations(6)|salt(24)|nonce(24)|ciphertext(N)]
|
|
115
|
+
*
|
|
116
|
+
* @param password The password to derive the encryption key from.
|
|
117
|
+
* @param keyToSave The hex-encoded secret key to encrypt.
|
|
118
|
+
* @param iterationOverride Optional PBKDF2 iteration count (random if omitted).
|
|
119
|
+
* @returns The encrypted key data as a Uint8Array.
|
|
120
|
+
*/
|
|
121
|
+
static encryptKeyData = (password, keyToSave, iterationOverride) => {
|
|
120
122
|
const UNENCRYPTED_SIGNKEY = XUtils.decodeHex(keyToSave);
|
|
121
123
|
const OFFSET = 1000;
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
const rand = nacl.randomBytes(2);
|
|
125
|
+
const [N1 = 0, N2 = 0] = rand;
|
|
126
|
+
const iterations = iterationOverride !== undefined && iterationOverride !== 0
|
|
127
|
+
? iterationOverride
|
|
128
|
+
: N1 * N2 + OFFSET;
|
|
127
129
|
const ITERATIONS = XUtils.numberToUint8Arr(iterations);
|
|
128
130
|
const PKBDF_SALT = xMakeNonce();
|
|
129
|
-
const ENCRYPTION_KEY =
|
|
131
|
+
const ENCRYPTION_KEY = noblePbkdf2(sha512, password, PKBDF_SALT, {
|
|
132
|
+
c: iterations,
|
|
133
|
+
dkLen: 32,
|
|
134
|
+
});
|
|
130
135
|
const NONCE = xMakeNonce();
|
|
131
|
-
const ENCRYPTED_SIGNKEY = nacl.secretbox(UNENCRYPTED_SIGNKEY, NONCE,
|
|
136
|
+
const ENCRYPTED_SIGNKEY = nacl.secretbox(UNENCRYPTED_SIGNKEY, NONCE, ENCRYPTION_KEY);
|
|
132
137
|
const result = new Uint8Array(ITERATIONS.length +
|
|
133
138
|
PKBDF_SALT.length +
|
|
134
139
|
NONCE.length +
|
|
@@ -141,58 +146,73 @@ export class XUtils {
|
|
|
141
146
|
result.set(NONCE, offset);
|
|
142
147
|
offset += NONCE.length;
|
|
143
148
|
result.set(ENCRYPTED_SIGNKEY, offset);
|
|
144
|
-
|
|
149
|
+
return result;
|
|
145
150
|
};
|
|
146
151
|
/**
|
|
147
|
-
*
|
|
152
|
+
* Returns a six bit Uint8Array representation of an integer.
|
|
153
|
+
* The integer must be positive, and it must be able to be stored
|
|
154
|
+
* in six bytes.
|
|
148
155
|
*
|
|
149
|
-
* @param
|
|
150
|
-
* @
|
|
156
|
+
* @param n The number to convert.
|
|
157
|
+
* @returns The Uint8Array representation of n.
|
|
151
158
|
*/
|
|
152
|
-
static
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const ENCRYPTION_NONCE = keyFile.slice(30, 54);
|
|
157
|
-
const ENCRYPTED_KEY = keyFile.slice(54);
|
|
158
|
-
const DERIVED_KEY = pbkdf2Sync(password, PKBDF_SALT, ITERATIONS, 32, "sha512");
|
|
159
|
-
const DECRYPTED_SIGNKEY = nacl.secretbox.open(ENCRYPTED_KEY, ENCRYPTION_NONCE, new Uint8Array(DERIVED_KEY));
|
|
160
|
-
if (!DECRYPTED_SIGNKEY) {
|
|
161
|
-
throw new Error("Decryption failed. Wrong password?");
|
|
159
|
+
static numberToUint8Arr(n) {
|
|
160
|
+
if (n < 0 || n > 281474976710655) {
|
|
161
|
+
throw new Error("Expected integer 0 < n < 281474976710655, received " +
|
|
162
|
+
String(n));
|
|
162
163
|
}
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
let str = n.toString(16);
|
|
165
|
+
while (str.length < 12) {
|
|
166
|
+
str = "0" + str;
|
|
165
167
|
}
|
|
166
|
-
|
|
168
|
+
return XUtils.decodeHex(str);
|
|
169
|
+
}
|
|
167
170
|
/**
|
|
168
|
-
*
|
|
171
|
+
* Packs a javascript object and a 32 byte header into a vex message.
|
|
169
172
|
*
|
|
170
|
-
* @
|
|
173
|
+
* @param arr The array to convert.
|
|
174
|
+
* @returns the packed message.
|
|
171
175
|
*/
|
|
172
|
-
static
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
static packMessage(msg, header) {
|
|
177
|
+
const msgb = msgpackEncode(msg);
|
|
178
|
+
const msgh = header ?? XUtils.emptyHeader();
|
|
179
|
+
return xConcat(msgh, msgb);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Converts a Uint8Array representation of an integer back into a number.
|
|
183
|
+
*
|
|
184
|
+
* @param arr The array to convert.
|
|
185
|
+
* @returns the number representation of arr.
|
|
186
|
+
*/
|
|
187
|
+
static uint8ArrToNumber(arr) {
|
|
188
|
+
let n = 0;
|
|
189
|
+
for (const byte of arr) {
|
|
190
|
+
n = n * 256 + byte;
|
|
175
191
|
}
|
|
176
|
-
return
|
|
192
|
+
return n;
|
|
177
193
|
}
|
|
178
194
|
/**
|
|
179
|
-
*
|
|
195
|
+
* Takes a vex message and unpacks it into its header and a javascript object
|
|
196
|
+
* respresentation of its body.
|
|
180
197
|
*
|
|
181
|
-
* @
|
|
198
|
+
* @param arr The array to convert.
|
|
199
|
+
* @returns [32 byte header, message body]
|
|
182
200
|
*/
|
|
183
|
-
static
|
|
184
|
-
|
|
201
|
+
static unpackMessage(msg) {
|
|
202
|
+
const msgp = Uint8Array.from(msg);
|
|
203
|
+
const msgh = msgp.slice(0, xConstants.HEADER_SIZE);
|
|
204
|
+
// Validate base fields exist, keep all extra fields for the caller to narrow
|
|
205
|
+
const raw = msgpackDecode(msgp.slice(xConstants.HEADER_SIZE));
|
|
206
|
+
const msgb = z
|
|
207
|
+
.object({
|
|
208
|
+
transmissionID: z.string(),
|
|
209
|
+
type: z.string(),
|
|
210
|
+
})
|
|
211
|
+
.loose()
|
|
212
|
+
.parse(raw);
|
|
213
|
+
return [msgh, msgb];
|
|
185
214
|
}
|
|
186
215
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Gets a word list representation of a byte sequence.
|
|
189
|
-
*
|
|
190
|
-
* @param entropy The bytes to derive the wordlist from.
|
|
191
|
-
* @param wordList Optional, override the wordlist. See bip39 docs for details.
|
|
192
|
-
*/
|
|
193
|
-
export function xMnemonic(entropy, wordList) {
|
|
194
|
-
return bip39.entropyToMnemonic(Buffer.from(entropy), wordList);
|
|
195
|
-
}
|
|
196
216
|
/**
|
|
197
217
|
* Returns a 32 byte HMAC of a javscript object.
|
|
198
218
|
*
|
|
@@ -201,10 +221,16 @@ export function xMnemonic(entropy, wordList) {
|
|
|
201
221
|
*/
|
|
202
222
|
export function xHMAC(msg, SK) {
|
|
203
223
|
const packedMsg = msgpackEncode(msg);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
224
|
+
return hmac(sha256, SK, packedMsg);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Gets a word list representation of a byte sequence.
|
|
228
|
+
*
|
|
229
|
+
* @param entropy The bytes to derive the wordlist from.
|
|
230
|
+
* @param wordList Optional, override the wordlist. See bip39 docs for details.
|
|
231
|
+
*/
|
|
232
|
+
export function xMnemonic(entropy, wordList) {
|
|
233
|
+
return bip39.entropyToMnemonic(XUtils.encodeHex(entropy), wordList);
|
|
208
234
|
}
|
|
209
235
|
/**
|
|
210
236
|
* Constants for vex.
|
|
@@ -212,55 +238,18 @@ export function xHMAC(msg, SK) {
|
|
|
212
238
|
export const xConstants = {
|
|
213
239
|
CURVE: "X25519",
|
|
214
240
|
HASH: "SHA-512",
|
|
215
|
-
|
|
241
|
+
HEADER_SIZE: 32,
|
|
216
242
|
INFO: "xchat",
|
|
243
|
+
KEY_LENGTH: 32,
|
|
217
244
|
MIN_OTK_SUPPLY: 100,
|
|
218
|
-
HEADER_SIZE: 32,
|
|
219
245
|
};
|
|
220
|
-
/**
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
export function xMakeNonce() {
|
|
224
|
-
return nacl.randomBytes(24);
|
|
246
|
+
/** Generate a fresh X25519 box key pair. */
|
|
247
|
+
export function xBoxKeyPair() {
|
|
248
|
+
return nacl.box.keyPair();
|
|
225
249
|
}
|
|
226
|
-
/**
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
* @param IKM the initial key material.
|
|
230
|
-
* @returns The generated key.
|
|
231
|
-
*/
|
|
232
|
-
// export function xKDF(IKM: Uint8Array): Uint8Array {
|
|
233
|
-
// return Uint8Array.from(
|
|
234
|
-
// hkdf(Buffer.from(IKM), xConstants.KEY_LENGTH, {
|
|
235
|
-
// salt: Buffer.from(xMakeSalt(xConstants.CURVE)),
|
|
236
|
-
// info: xConstants.INFO,
|
|
237
|
-
// hash: xConstants.HASH,
|
|
238
|
-
// })
|
|
239
|
-
// );
|
|
240
|
-
// }
|
|
241
|
-
export function xKDF(IKM) {
|
|
242
|
-
return new Uint8Array(hkdfSync("sha512", IKM, xMakeSalt(xConstants.CURVE), xConstants.INFO, xConstants.KEY_LENGTH));
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Hashes some data.
|
|
246
|
-
*
|
|
247
|
-
* @param data the data to hash.
|
|
248
|
-
* @returns The hash of the data.
|
|
249
|
-
*/
|
|
250
|
-
export function xHash(data) {
|
|
251
|
-
const hash = createHash("sha512");
|
|
252
|
-
return hash.update(data).digest("hex");
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Derives a shared Secret Key from a known private key and
|
|
256
|
-
* a peer's known public key.
|
|
257
|
-
*
|
|
258
|
-
* @param myPrivateKey Your own private key
|
|
259
|
-
* @param theirPublicKey Their public key
|
|
260
|
-
* @returns The derived shared secret, SK.
|
|
261
|
-
*/
|
|
262
|
-
export function xDH(myPrivateKey, theirPublicKey) {
|
|
263
|
-
return nacl.box.before(theirPublicKey, myPrivateKey);
|
|
250
|
+
/** Restore an X25519 box key pair from a 32-byte secret key. */
|
|
251
|
+
export function xBoxKeyPairFromSecret(secretKey) {
|
|
252
|
+
return nacl.box.keyPair.fromSecretKey(secretKey);
|
|
264
253
|
}
|
|
265
254
|
/**
|
|
266
255
|
* Concatanates multiple Uint8Arrays.
|
|
@@ -269,7 +258,7 @@ export function xDH(myPrivateKey, theirPublicKey) {
|
|
|
269
258
|
*/
|
|
270
259
|
export function xConcat(...arrays) {
|
|
271
260
|
const totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
|
|
272
|
-
if (
|
|
261
|
+
if (arrays.length === 0) {
|
|
273
262
|
return new Uint8Array();
|
|
274
263
|
}
|
|
275
264
|
const result = new Uint8Array(totalLength);
|
|
@@ -282,6 +271,18 @@ export function xConcat(...arrays) {
|
|
|
282
271
|
}
|
|
283
272
|
return result;
|
|
284
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Derives a shared Secret Key from a known private key and
|
|
276
|
+
* a peer's known public key.
|
|
277
|
+
*
|
|
278
|
+
* @param myPrivateKey Your own private key
|
|
279
|
+
* @param theirPublicKey Their public key
|
|
280
|
+
* @returns The derived shared secret, SK.
|
|
281
|
+
*/
|
|
282
|
+
export function xDH(myPrivateKey, theirPublicKey) {
|
|
283
|
+
return nacl.box.before(theirPublicKey, myPrivateKey);
|
|
284
|
+
}
|
|
285
|
+
// ── Key pair type ───────────────────────────────────────────────────────────
|
|
285
286
|
/**
|
|
286
287
|
* Encode an X25519 or X448 public key PK into a byte sequence.
|
|
287
288
|
* The encoding consists of 0 or 1 to represent the type of curve, followed by l
|
|
@@ -291,17 +292,17 @@ export function xConcat(...arrays) {
|
|
|
291
292
|
export function xEncode(curveType, publicKey) {
|
|
292
293
|
if (publicKey.length !== 32) {
|
|
293
294
|
throw new Error("Invalid key length, received key of length " +
|
|
294
|
-
publicKey.length +
|
|
295
|
+
String(publicKey.length) +
|
|
295
296
|
" and expected length 32.");
|
|
296
297
|
}
|
|
297
298
|
const bytes = [];
|
|
298
299
|
switch (curveType) {
|
|
299
|
-
case "X25519":
|
|
300
|
-
bytes.push(0);
|
|
301
|
-
break;
|
|
302
300
|
case "X448":
|
|
303
301
|
bytes.push(1);
|
|
304
302
|
break;
|
|
303
|
+
case "X25519":
|
|
304
|
+
bytes.push(0);
|
|
305
|
+
break;
|
|
305
306
|
}
|
|
306
307
|
const key = BigInt("0x" + XUtils.encodeHex(publicKey));
|
|
307
308
|
if (isEven(key)) {
|
|
@@ -315,22 +316,55 @@ export function xEncode(curveType, publicKey) {
|
|
|
315
316
|
}
|
|
316
317
|
return Uint8Array.from(bytes);
|
|
317
318
|
}
|
|
319
|
+
// ── Key generation ─────────────────────────────────────────────────────────
|
|
318
320
|
/**
|
|
319
|
-
*
|
|
321
|
+
* Hashes some data.
|
|
322
|
+
*
|
|
323
|
+
* @param data the data to hash.
|
|
324
|
+
* @returns The hash of the data.
|
|
320
325
|
*/
|
|
321
|
-
function
|
|
322
|
-
return
|
|
326
|
+
export function xHash(data) {
|
|
327
|
+
return XUtils.encodeHex(sha512(data));
|
|
328
|
+
}
|
|
329
|
+
export function xKDF(IKM) {
|
|
330
|
+
return hkdf(sha512, IKM, xMakeSalt(xConstants.CURVE), new TextEncoder().encode(xConstants.INFO), xConstants.KEY_LENGTH);
|
|
323
331
|
}
|
|
324
332
|
/**
|
|
325
|
-
*
|
|
333
|
+
* Returns a 24 byte random nonce of cryptographic quality.
|
|
326
334
|
*/
|
|
327
|
-
function
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
335
|
+
export function xMakeNonce() {
|
|
336
|
+
return nacl.randomBytes(24);
|
|
337
|
+
}
|
|
338
|
+
/** Cryptographically secure random bytes. */
|
|
339
|
+
export function xRandomBytes(length) {
|
|
340
|
+
return nacl.randomBytes(length);
|
|
341
|
+
}
|
|
342
|
+
// ── Signing ────────────────────────────────────────────────────────────────
|
|
343
|
+
/** Encrypt with a shared secret key. */
|
|
344
|
+
export function xSecretbox(plaintext, nonce, key) {
|
|
345
|
+
return nacl.secretbox(plaintext, nonce, key);
|
|
346
|
+
}
|
|
347
|
+
/** Decrypt with a shared secret key. Returns null if authentication fails. */
|
|
348
|
+
export function xSecretboxOpen(ciphertext, nonce, key) {
|
|
349
|
+
return nacl.secretbox.open(ciphertext, nonce, key);
|
|
350
|
+
}
|
|
351
|
+
// ── Symmetric encryption (XSalsa20-Poly1305) ──────────────────────────────
|
|
352
|
+
/** Sign a message with an Ed25519 secret key. Returns signed message (64-byte signature prefix + message). */
|
|
353
|
+
export function xSign(message, secretKey) {
|
|
354
|
+
return nacl.sign(message, secretKey);
|
|
355
|
+
}
|
|
356
|
+
/** Generate a fresh Ed25519 signing key pair. */
|
|
357
|
+
export function xSignKeyPair() {
|
|
358
|
+
return nacl.sign.keyPair();
|
|
359
|
+
}
|
|
360
|
+
// ── Random ─────────────────────────────────────────────────────────────────
|
|
361
|
+
/** Restore an Ed25519 signing key pair from a 64-byte secret key. */
|
|
362
|
+
export function xSignKeyPairFromSecret(secretKey) {
|
|
363
|
+
return nacl.sign.keyPair.fromSecretKey(secretKey);
|
|
364
|
+
}
|
|
365
|
+
/** Verify and open a signed message. Returns the original message, or null if verification fails. */
|
|
366
|
+
export function xSignOpen(signedMessage, publicKey) {
|
|
367
|
+
return nacl.sign.open(signedMessage, publicKey);
|
|
334
368
|
}
|
|
335
369
|
/**
|
|
336
370
|
* @ignore
|
|
@@ -343,3 +377,18 @@ function isEven(value) {
|
|
|
343
377
|
return false;
|
|
344
378
|
}
|
|
345
379
|
}
|
|
380
|
+
/**
|
|
381
|
+
* @ignore
|
|
382
|
+
*/
|
|
383
|
+
function keyLength(curve) {
|
|
384
|
+
return curve === "X25519" ? 32 : 57;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* @ignore
|
|
388
|
+
*/
|
|
389
|
+
function xMakeSalt(curve) {
|
|
390
|
+
const salt = new Uint8Array(keyLength(curve));
|
|
391
|
+
salt.fill(0xff);
|
|
392
|
+
return salt;
|
|
393
|
+
}
|
|
394
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|