@brashkie/signalis-core 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/dist/index.cjs ADDED
@@ -0,0 +1,712 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AES_256_CBC_IV_SIZE: () => AES_256_CBC_IV_SIZE,
34
+ AES_256_GCM_NONCE_SIZE: () => AES_256_GCM_NONCE_SIZE,
35
+ AES_256_GCM_TAG_SIZE: () => AES_256_GCM_TAG_SIZE,
36
+ AES_256_KEY_SIZE: () => AES_256_KEY_SIZE,
37
+ AES_BLOCK_SIZE: () => AES_BLOCK_SIZE,
38
+ AES_CBC: () => AES_CBC,
39
+ AES_GCM: () => AES_GCM,
40
+ AES_GCM_MAX_PLAINTEXT_SIZE: () => AES_GCM_MAX_PLAINTEXT_SIZE,
41
+ AES_GCM_RECOMMENDED_MESSAGES_PER_KEY: () => AES_GCM_RECOMMENDED_MESSAGES_PER_KEY,
42
+ AuthenticationError: () => AuthenticationError,
43
+ CURVE25519_PRIVATE_KEY_SIZE: () => CURVE25519_PRIVATE_KEY_SIZE,
44
+ CURVE25519_PUBLIC_KEY_SIZE: () => CURVE25519_PUBLIC_KEY_SIZE,
45
+ CURVE25519_SHARED_SECRET_SIZE: () => CURVE25519_SHARED_SECRET_SIZE,
46
+ CryptoError: () => CryptoError,
47
+ Curve25519: () => Curve25519,
48
+ HKDF: () => HKDF,
49
+ HKDF_MAX_OUTPUT_SIZE: () => HKDF_MAX_OUTPUT_SIZE,
50
+ HKDF_PRK_SIZE: () => HKDF_PRK_SIZE,
51
+ HMAC: () => HMAC,
52
+ HMAC_SHA256_TAG_SIZE: () => HMAC_SHA256_TAG_SIZE,
53
+ KeyDerivationError: () => KeyDerivationError,
54
+ LengthError: () => LengthError,
55
+ SHA256: () => SHA256,
56
+ SHA256_BLOCK_SIZE: () => SHA256_BLOCK_SIZE,
57
+ SHA256_OUTPUT_SIZE: () => SHA256_OUTPUT_SIZE,
58
+ SignalisError: () => SignalisError,
59
+ VERSION: () => VERSION,
60
+ ValidationError: () => ValidationError,
61
+ asPrivateKey: () => asPrivateKey,
62
+ asPublicKey: () => asPublicKey,
63
+ asSharedSecret: () => asSharedSecret,
64
+ assertBuffer: () => assertBuffer,
65
+ assertBufferLength: () => assertBufferLength,
66
+ assertBufferOfSize: () => assertBufferOfSize,
67
+ assertHkdfLength: () => assertHkdfLength,
68
+ assertPositiveInteger: () => assertPositiveInteger,
69
+ bufferToString: () => bufferToString,
70
+ buffersSameLength: () => buffersSameLength,
71
+ concat: () => concat,
72
+ constantTimeEqual: () => constantTimeEqual,
73
+ default: () => index_default,
74
+ fromBase64: () => fromBase64,
75
+ fromBase64Url: () => fromBase64Url,
76
+ fromHex: () => fromHex,
77
+ nativeVersion: () => nativeVersion,
78
+ randomIv: () => randomIv,
79
+ randomKey: () => randomKey,
80
+ randomNonce: () => randomNonce,
81
+ secureRandom: () => secureRandom,
82
+ stringToBuffer: () => stringToBuffer,
83
+ toBase64: () => toBase64,
84
+ toBase64Url: () => toBase64Url,
85
+ toHex: () => toHex,
86
+ xor: () => xor,
87
+ zeroize: () => zeroize
88
+ });
89
+ module.exports = __toCommonJS(index_exports);
90
+
91
+ // src/core.ts
92
+ var native = __toESM(require("../index.js"));
93
+
94
+ // src/constants.ts
95
+ var CURVE25519_PRIVATE_KEY_SIZE = 32;
96
+ var CURVE25519_PUBLIC_KEY_SIZE = 32;
97
+ var CURVE25519_SHARED_SECRET_SIZE = 32;
98
+ var HKDF_PRK_SIZE = 32;
99
+ var HKDF_MAX_OUTPUT_SIZE = 8160;
100
+ var AES_256_KEY_SIZE = 32;
101
+ var AES_256_GCM_NONCE_SIZE = 12;
102
+ var AES_256_GCM_TAG_SIZE = 16;
103
+ var AES_256_CBC_IV_SIZE = 16;
104
+ var AES_BLOCK_SIZE = 16;
105
+ var SHA256_OUTPUT_SIZE = 32;
106
+ var HMAC_SHA256_TAG_SIZE = 32;
107
+ var SHA256_BLOCK_SIZE = 64;
108
+ var AES_GCM_MAX_PLAINTEXT_SIZE = 64 * 1024 * 1024 * 1024;
109
+ var AES_GCM_RECOMMENDED_MESSAGES_PER_KEY = 4294967296;
110
+
111
+ // src/errors.ts
112
+ var SignalisError = class extends Error {
113
+ /** Error code for programmatic handling. */
114
+ code;
115
+ constructor(message, code) {
116
+ super(message);
117
+ this.name = "SignalisError";
118
+ this.code = code;
119
+ if (typeof Error.captureStackTrace === "function") {
120
+ Error.captureStackTrace(this, this.constructor);
121
+ }
122
+ }
123
+ };
124
+ var ValidationError = class extends SignalisError {
125
+ /** Name of the parameter that failed validation. */
126
+ parameter;
127
+ /** Expected value description. */
128
+ expected;
129
+ /** Actual value received. */
130
+ actual;
131
+ constructor(message, options = {}) {
132
+ super(message, "VALIDATION_ERROR");
133
+ this.name = "ValidationError";
134
+ this.parameter = options.parameter;
135
+ this.expected = options.expected;
136
+ this.actual = options.actual;
137
+ }
138
+ };
139
+ var CryptoError = class extends SignalisError {
140
+ /** The crypto operation that failed. */
141
+ operation;
142
+ constructor(message, operation) {
143
+ super(message, "CRYPTO_ERROR");
144
+ this.name = "CryptoError";
145
+ this.operation = operation;
146
+ }
147
+ };
148
+ var AuthenticationError = class extends CryptoError {
149
+ constructor(message = "Authentication tag verification failed") {
150
+ super(message, "authenticate");
151
+ this.name = "AuthenticationError";
152
+ }
153
+ };
154
+ var KeyDerivationError = class extends CryptoError {
155
+ constructor(message) {
156
+ super(message, "derive_key");
157
+ this.name = "KeyDerivationError";
158
+ }
159
+ };
160
+ var LengthError = class extends ValidationError {
161
+ constructor(message, options = {}) {
162
+ super(message, options);
163
+ this.name = "LengthError";
164
+ }
165
+ };
166
+
167
+ // src/validators.ts
168
+ function assertBuffer(value, parameter) {
169
+ if (!Buffer.isBuffer(value)) {
170
+ throw new ValidationError(`${parameter} must be a Buffer`, {
171
+ parameter,
172
+ expected: "Buffer",
173
+ actual: typeof value
174
+ });
175
+ }
176
+ }
177
+ function assertBufferLength(value, expectedLength, parameter) {
178
+ if (value.length !== expectedLength) {
179
+ throw new ValidationError(
180
+ `${parameter} must be ${expectedLength} bytes, got ${value.length}`,
181
+ {
182
+ parameter,
183
+ expected: `${expectedLength} bytes`,
184
+ actual: value.length
185
+ }
186
+ );
187
+ }
188
+ }
189
+ function assertBufferOfSize(value, expectedLength, parameter) {
190
+ assertBuffer(value, parameter);
191
+ assertBufferLength(value, expectedLength, parameter);
192
+ }
193
+ function assertPositiveInteger(value, parameter) {
194
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
195
+ throw new ValidationError(`${parameter} must be a non-negative integer`, {
196
+ parameter,
197
+ expected: "non-negative integer",
198
+ actual: String(value)
199
+ });
200
+ }
201
+ }
202
+ function assertHkdfLength(length) {
203
+ assertPositiveInteger(length, "length");
204
+ if (length > HKDF_MAX_OUTPUT_SIZE) {
205
+ throw new LengthError(
206
+ `HKDF output length cannot exceed ${HKDF_MAX_OUTPUT_SIZE} bytes (255 * 32)`,
207
+ {
208
+ expected: `<= ${HKDF_MAX_OUTPUT_SIZE}`,
209
+ actual: length
210
+ }
211
+ );
212
+ }
213
+ if (length === 0) {
214
+ throw new LengthError("HKDF output length must be greater than 0", {
215
+ expected: "> 0",
216
+ actual: 0
217
+ });
218
+ }
219
+ }
220
+ function buffersSameLength(a, b) {
221
+ return a.length === b.length;
222
+ }
223
+
224
+ // src/core.ts
225
+ var Curve25519 = Object.freeze({
226
+ /**
227
+ * Generate a new random Curve25519 keypair.
228
+ *
229
+ * Uses the OS's cryptographically secure RNG (via Rust's `OsRng`).
230
+ *
231
+ * @returns A {@link KeyPair} with private and public keys (32 bytes each)
232
+ */
233
+ generateKeyPair() {
234
+ const kp = native.curve25519GenerateKeypair();
235
+ return Object.freeze({
236
+ privateKey: kp.private,
237
+ publicKey: kp.public
238
+ });
239
+ },
240
+ /**
241
+ * Derive the public key corresponding to a given private key.
242
+ *
243
+ * @param privateKey - 32-byte private key
244
+ * @returns The corresponding 32-byte public key
245
+ * @throws {ValidationError} If `privateKey` is not a 32-byte Buffer.
246
+ */
247
+ publicFromPrivate(privateKey) {
248
+ assertBufferOfSize(privateKey, CURVE25519_PRIVATE_KEY_SIZE, "privateKey");
249
+ return native.curve25519PublicFromPrivate(privateKey);
250
+ },
251
+ /**
252
+ * Perform X25519 Diffie-Hellman key agreement.
253
+ *
254
+ * Both parties run this with swapped (private, peer-public) arguments
255
+ * and obtain the same 32-byte shared secret.
256
+ *
257
+ * **⚠️ CRITICAL:** Do NOT use the returned secret directly as an
258
+ * encryption key. Always derive an actual key through HKDF:
259
+ *
260
+ * @example
261
+ * ```ts
262
+ * const shared = Curve25519.diffieHellman(myPriv, theirPub);
263
+ * const key = HKDF.derive(salt, shared, Buffer.from('aes-key'), 32);
264
+ * ```
265
+ *
266
+ * @param privateKey - Your 32-byte private key
267
+ * @param peerPublicKey - Peer's 32-byte public key
268
+ * @returns 32-byte shared secret
269
+ * @throws {ValidationError} If keys are not 32 bytes.
270
+ * @throws {CryptoError} If the operation fails.
271
+ */
272
+ diffieHellman(privateKey, peerPublicKey) {
273
+ assertBufferOfSize(privateKey, CURVE25519_PRIVATE_KEY_SIZE, "privateKey");
274
+ assertBufferOfSize(peerPublicKey, CURVE25519_PUBLIC_KEY_SIZE, "peerPublicKey");
275
+ return native.curve25519DiffieHellman(privateKey, peerPublicKey);
276
+ },
277
+ /**
278
+ * The size of a Curve25519 private key in bytes (32).
279
+ */
280
+ PRIVATE_KEY_SIZE: CURVE25519_PRIVATE_KEY_SIZE,
281
+ /**
282
+ * The size of a Curve25519 public key in bytes (32).
283
+ */
284
+ PUBLIC_KEY_SIZE: CURVE25519_PUBLIC_KEY_SIZE,
285
+ /**
286
+ * The size of an X25519 shared secret in bytes (32).
287
+ */
288
+ SHARED_SECRET_SIZE: CURVE25519_SHARED_SECRET_SIZE
289
+ });
290
+ var HKDF = Object.freeze({
291
+ /**
292
+ * HKDF-Extract: produces a 32-byte pseudorandom key (PRK).
293
+ *
294
+ * @param salt - Optional salt (pass `Buffer.alloc(0)` if not available)
295
+ * @param ikm - Input keying material
296
+ * @returns 32-byte PRK
297
+ * @throws {ValidationError} If inputs are not Buffers.
298
+ */
299
+ extract(salt, ikm) {
300
+ assertBuffer(salt, "salt");
301
+ assertBuffer(ikm, "ikm");
302
+ return native.hkdfExtract(salt, ikm);
303
+ },
304
+ /**
305
+ * HKDF-Expand: produces `length` bytes of output keying material.
306
+ *
307
+ * @param prk - 32-byte pseudorandom key from {@link extract}
308
+ * @param info - Context-specific information (binds output to a usage)
309
+ * @param length - Desired output length (1 to 8160 bytes)
310
+ * @returns OKM of requested length
311
+ * @throws {ValidationError} If PRK is not 32 bytes or length is out of bounds.
312
+ */
313
+ expand(prk, info, length) {
314
+ assertBufferOfSize(prk, HKDF_PRK_SIZE, "prk");
315
+ assertBuffer(info, "info");
316
+ assertHkdfLength(length);
317
+ return native.hkdfExpand(prk, info, length);
318
+ },
319
+ /**
320
+ * HKDF one-shot: extract + expand in a single call.
321
+ *
322
+ * Use this whenever possible — it's the standard HKDF API.
323
+ *
324
+ * @param salt - Optional salt
325
+ * @param ikm - Input keying material
326
+ * @param info - Context info
327
+ * @param length - Desired output length
328
+ * @returns OKM of requested length
329
+ */
330
+ derive(salt, ikm, info, length) {
331
+ assertBuffer(salt, "salt");
332
+ assertBuffer(ikm, "ikm");
333
+ assertBuffer(info, "info");
334
+ assertHkdfLength(length);
335
+ return native.hkdfDerive(salt, ikm, info, length);
336
+ },
337
+ /**
338
+ * Derive multiple keys from the same shared secret in a single call.
339
+ *
340
+ * Useful for deriving e.g., a send key AND a receive key simultaneously.
341
+ *
342
+ * @example
343
+ * ```ts
344
+ * const [sendKey, recvKey] = HKDF.deriveMultiple(
345
+ * salt,
346
+ * sharedSecret,
347
+ * Buffer.from('signalis-channel-v1'),
348
+ * [32, 32],
349
+ * );
350
+ * ```
351
+ *
352
+ * @param salt - Optional salt
353
+ * @param ikm - Input keying material
354
+ * @param info - Context info
355
+ * @param lengths - Array of output lengths
356
+ * @returns Array of derived keys, one per requested length
357
+ */
358
+ deriveMultiple(salt, ikm, info, lengths) {
359
+ assertBuffer(salt, "salt");
360
+ assertBuffer(ikm, "ikm");
361
+ assertBuffer(info, "info");
362
+ if (!Array.isArray(lengths) || lengths.length === 0) {
363
+ throw new TypeError("lengths must be a non-empty array of integers");
364
+ }
365
+ const total = lengths.reduce((sum, len) => sum + len, 0);
366
+ assertHkdfLength(total);
367
+ const okm = this.derive(salt, ikm, info, total);
368
+ const results = [];
369
+ let offset = 0;
370
+ for (const len of lengths) {
371
+ results.push(okm.subarray(offset, offset + len));
372
+ offset += len;
373
+ }
374
+ return results;
375
+ },
376
+ /**
377
+ * Derive a key using an {@link HkdfParams} object (alternative API).
378
+ */
379
+ deriveFromParams(params) {
380
+ return this.derive(params.salt, params.ikm, params.info, params.length);
381
+ },
382
+ /**
383
+ * The size of an HKDF PRK in bytes (32).
384
+ */
385
+ PRK_SIZE: HKDF_PRK_SIZE
386
+ });
387
+ var AES_GCM = Object.freeze({
388
+ /**
389
+ * Encrypt plaintext.
390
+ *
391
+ * Returns: ciphertext || 16-byte authentication tag (concatenated).
392
+ *
393
+ * @param key - 32-byte symmetric key
394
+ * @param nonce - 12-byte unique nonce (NEVER reuse with same key)
395
+ * @param plaintext - Data to encrypt
396
+ * @returns Ciphertext + auth tag (output is `plaintext.length + 16` bytes)
397
+ * @throws {ValidationError} On invalid sizes.
398
+ * @throws {CryptoError} If the operation fails.
399
+ */
400
+ encrypt(key, nonce, plaintext) {
401
+ assertBufferOfSize(key, AES_256_KEY_SIZE, "key");
402
+ assertBufferOfSize(nonce, AES_256_GCM_NONCE_SIZE, "nonce");
403
+ assertBuffer(plaintext, "plaintext");
404
+ return native.aes256GcmEncrypt(key, nonce, plaintext);
405
+ },
406
+ /**
407
+ * Decrypt ciphertext and verify authentication tag.
408
+ *
409
+ * @param key - 32-byte symmetric key (same as encryption)
410
+ * @param nonce - 12-byte nonce (same as encryption)
411
+ * @param ciphertext - Ciphertext || auth tag
412
+ * @returns Original plaintext
413
+ * @throws {ValidationError} On invalid sizes.
414
+ * @throws {AuthenticationError} If the tag is invalid (tampered or wrong key).
415
+ */
416
+ decrypt(key, nonce, ciphertext) {
417
+ assertBufferOfSize(key, AES_256_KEY_SIZE, "key");
418
+ assertBufferOfSize(nonce, AES_256_GCM_NONCE_SIZE, "nonce");
419
+ assertBuffer(ciphertext, "ciphertext");
420
+ if (ciphertext.length < AES_256_GCM_TAG_SIZE) {
421
+ throw new CryptoError(
422
+ `Ciphertext too short: must be at least ${AES_256_GCM_TAG_SIZE} bytes (tag size)`,
423
+ "aes_gcm_decrypt"
424
+ );
425
+ }
426
+ try {
427
+ return native.aes256GcmDecrypt(key, nonce, ciphertext);
428
+ } catch (e) {
429
+ throw new AuthenticationError(
430
+ `AES-256-GCM authentication failed: ${e.message}`
431
+ );
432
+ }
433
+ },
434
+ /** Key size in bytes (32). */
435
+ KEY_SIZE: AES_256_KEY_SIZE,
436
+ /** Nonce size in bytes (12). */
437
+ NONCE_SIZE: AES_256_GCM_NONCE_SIZE,
438
+ /** Tag size in bytes (16). */
439
+ TAG_SIZE: AES_256_GCM_TAG_SIZE
440
+ });
441
+ var AES_CBC = Object.freeze({
442
+ /**
443
+ * Encrypt with PKCS#7 padding.
444
+ *
445
+ * @param key - 32-byte symmetric key
446
+ * @param iv - 16-byte initialization vector
447
+ * @param plaintext - Data to encrypt
448
+ * @returns Ciphertext (padded to nearest 16-byte block)
449
+ */
450
+ encrypt(key, iv, plaintext) {
451
+ assertBufferOfSize(key, AES_256_KEY_SIZE, "key");
452
+ assertBufferOfSize(iv, AES_256_CBC_IV_SIZE, "iv");
453
+ assertBuffer(plaintext, "plaintext");
454
+ return native.aes256CbcEncrypt(key, iv, plaintext);
455
+ },
456
+ /**
457
+ * Decrypt with PKCS#7 padding (no authentication).
458
+ *
459
+ * @param key - 32-byte symmetric key
460
+ * @param iv - 16-byte IV (same as encryption)
461
+ * @param ciphertext - Ciphertext
462
+ * @returns Original plaintext
463
+ * @throws {CryptoError} On padding errors.
464
+ */
465
+ decrypt(key, iv, ciphertext) {
466
+ assertBufferOfSize(key, AES_256_KEY_SIZE, "key");
467
+ assertBufferOfSize(iv, AES_256_CBC_IV_SIZE, "iv");
468
+ assertBuffer(ciphertext, "ciphertext");
469
+ try {
470
+ return native.aes256CbcDecrypt(key, iv, ciphertext);
471
+ } catch (e) {
472
+ throw new CryptoError(
473
+ `AES-256-CBC decryption failed: ${e.message}`,
474
+ "aes_cbc_decrypt"
475
+ );
476
+ }
477
+ },
478
+ /** Key size in bytes (32). */
479
+ KEY_SIZE: AES_256_KEY_SIZE,
480
+ /** IV size in bytes (16). */
481
+ IV_SIZE: AES_256_CBC_IV_SIZE
482
+ });
483
+ var HMAC = Object.freeze({
484
+ /**
485
+ * Compute HMAC-SHA256 of `data` using `key`.
486
+ *
487
+ * @param key - Authentication key (any length)
488
+ * @param data - Data to authenticate
489
+ * @returns 32-byte HMAC tag
490
+ */
491
+ sha256(key, data) {
492
+ assertBuffer(key, "key");
493
+ assertBuffer(data, "data");
494
+ return native.hmacSha256(key, data);
495
+ },
496
+ /**
497
+ * Verify an HMAC-SHA256 tag in **constant time**.
498
+ *
499
+ * Always use this instead of `===` to prevent timing attacks.
500
+ *
501
+ * @param key - Authentication key
502
+ * @param data - Original data
503
+ * @param expectedTag - Tag to verify
504
+ * @returns `true` if tag matches, `false` otherwise
505
+ */
506
+ verifySha256(key, data, expectedTag) {
507
+ assertBuffer(key, "key");
508
+ assertBuffer(data, "data");
509
+ assertBuffer(expectedTag, "expectedTag");
510
+ return native.hmacSha256Verify(key, data, expectedTag);
511
+ },
512
+ /** Tag size in bytes (32). */
513
+ TAG_SIZE: HMAC_SHA256_TAG_SIZE
514
+ });
515
+ var SHA256 = Object.freeze({
516
+ /**
517
+ * Compute SHA-256 hash of `data`.
518
+ *
519
+ * @param data - Data to hash
520
+ * @returns 32-byte digest
521
+ */
522
+ hash(data) {
523
+ assertBuffer(data, "data");
524
+ return native.sha256(data);
525
+ },
526
+ /**
527
+ * Hash multiple Buffers concatenated together.
528
+ *
529
+ * Equivalent to `SHA256.hash(Buffer.concat([...]))` but slightly more
530
+ * efficient (avoids the intermediate concat).
531
+ */
532
+ hashAll(buffers) {
533
+ if (!Array.isArray(buffers)) {
534
+ throw new TypeError("buffers must be an array");
535
+ }
536
+ for (let i = 0; i < buffers.length; i++) {
537
+ assertBuffer(buffers[i], `buffers[${i}]`);
538
+ }
539
+ return this.hash(Buffer.concat(buffers));
540
+ },
541
+ /** Output size in bytes (32). */
542
+ OUTPUT_SIZE: SHA256_OUTPUT_SIZE
543
+ });
544
+ var nativeVersion = native.version();
545
+
546
+ // src/types.ts
547
+ function asPublicKey(buf) {
548
+ return buf;
549
+ }
550
+ function asPrivateKey(buf) {
551
+ return buf;
552
+ }
553
+ function asSharedSecret(buf) {
554
+ return buf;
555
+ }
556
+
557
+ // src/utils.ts
558
+ var import_node_crypto = require("crypto");
559
+ function secureRandom(length) {
560
+ if (!Number.isInteger(length) || length < 0) {
561
+ throw new RangeError(`length must be a non-negative integer, got ${length}`);
562
+ }
563
+ return (0, import_node_crypto.randomBytes)(length);
564
+ }
565
+ function randomNonce() {
566
+ return (0, import_node_crypto.randomBytes)(12);
567
+ }
568
+ function randomIv() {
569
+ return (0, import_node_crypto.randomBytes)(16);
570
+ }
571
+ function randomKey() {
572
+ return (0, import_node_crypto.randomBytes)(32);
573
+ }
574
+ function toHex(buf) {
575
+ return buf.toString("hex");
576
+ }
577
+ function fromHex(hex) {
578
+ if (!/^[0-9a-fA-F]*$/.test(hex)) {
579
+ throw new Error("Invalid hex string: contains non-hex characters");
580
+ }
581
+ if (hex.length % 2 !== 0) {
582
+ throw new Error("Invalid hex string: odd number of characters");
583
+ }
584
+ return Buffer.from(hex, "hex");
585
+ }
586
+ function toBase64(buf) {
587
+ return buf.toString("base64");
588
+ }
589
+ function fromBase64(b64) {
590
+ return Buffer.from(b64, "base64");
591
+ }
592
+ function toBase64Url(buf) {
593
+ return buf.toString("base64url");
594
+ }
595
+ function fromBase64Url(b64url) {
596
+ return Buffer.from(b64url, "base64url");
597
+ }
598
+ function bufferToString(buf, encoding = "hex") {
599
+ return buf.toString(encoding);
600
+ }
601
+ function stringToBuffer(str, encoding = "hex") {
602
+ return Buffer.from(str, encoding);
603
+ }
604
+ function constantTimeEqual(a, b) {
605
+ if (a.length !== b.length) {
606
+ (0, import_node_crypto.timingSafeEqual)(a, a);
607
+ return false;
608
+ }
609
+ return (0, import_node_crypto.timingSafeEqual)(a, b);
610
+ }
611
+ function concat(buffers) {
612
+ return Buffer.concat(buffers);
613
+ }
614
+ function zeroize(buf) {
615
+ buf.fill(0);
616
+ }
617
+ function xor(a, b) {
618
+ if (a.length !== b.length) {
619
+ throw new Error(`XOR operands must have equal length: ${a.length} vs ${b.length}`);
620
+ }
621
+ const result = Buffer.alloc(a.length);
622
+ for (let i = 0; i < a.length; i++) {
623
+ result[i] = a[i] ^ b[i];
624
+ }
625
+ return result;
626
+ }
627
+
628
+ // src/index.ts
629
+ var VERSION = "0.1.0";
630
+ var SignalisCore = Object.freeze({
631
+ // Crypto primitives
632
+ Curve25519,
633
+ HKDF,
634
+ AES_GCM,
635
+ AES_CBC,
636
+ HMAC,
637
+ SHA256,
638
+ // Random
639
+ secureRandom,
640
+ randomNonce,
641
+ randomIv,
642
+ randomKey,
643
+ // Encoding
644
+ toHex,
645
+ fromHex,
646
+ toBase64,
647
+ fromBase64,
648
+ // Security
649
+ constantTimeEqual,
650
+ // Version
651
+ VERSION: "0.1.0",
652
+ nativeVersion
653
+ });
654
+ var index_default = SignalisCore;
655
+ // Annotate the CommonJS export names for ESM import in node:
656
+ 0 && (module.exports = {
657
+ AES_256_CBC_IV_SIZE,
658
+ AES_256_GCM_NONCE_SIZE,
659
+ AES_256_GCM_TAG_SIZE,
660
+ AES_256_KEY_SIZE,
661
+ AES_BLOCK_SIZE,
662
+ AES_CBC,
663
+ AES_GCM,
664
+ AES_GCM_MAX_PLAINTEXT_SIZE,
665
+ AES_GCM_RECOMMENDED_MESSAGES_PER_KEY,
666
+ AuthenticationError,
667
+ CURVE25519_PRIVATE_KEY_SIZE,
668
+ CURVE25519_PUBLIC_KEY_SIZE,
669
+ CURVE25519_SHARED_SECRET_SIZE,
670
+ CryptoError,
671
+ Curve25519,
672
+ HKDF,
673
+ HKDF_MAX_OUTPUT_SIZE,
674
+ HKDF_PRK_SIZE,
675
+ HMAC,
676
+ HMAC_SHA256_TAG_SIZE,
677
+ KeyDerivationError,
678
+ LengthError,
679
+ SHA256,
680
+ SHA256_BLOCK_SIZE,
681
+ SHA256_OUTPUT_SIZE,
682
+ SignalisError,
683
+ VERSION,
684
+ ValidationError,
685
+ asPrivateKey,
686
+ asPublicKey,
687
+ asSharedSecret,
688
+ assertBuffer,
689
+ assertBufferLength,
690
+ assertBufferOfSize,
691
+ assertHkdfLength,
692
+ assertPositiveInteger,
693
+ bufferToString,
694
+ buffersSameLength,
695
+ concat,
696
+ constantTimeEqual,
697
+ fromBase64,
698
+ fromBase64Url,
699
+ fromHex,
700
+ nativeVersion,
701
+ randomIv,
702
+ randomKey,
703
+ randomNonce,
704
+ secureRandom,
705
+ stringToBuffer,
706
+ toBase64,
707
+ toBase64Url,
708
+ toHex,
709
+ xor,
710
+ zeroize
711
+ });
712
+ //# sourceMappingURL=index.cjs.map