@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.
@@ -0,0 +1,764 @@
1
+ /**
2
+ * Shared TypeScript types for signalis-core.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ /**
7
+ * A Curve25519 keypair (private + public key).
8
+ *
9
+ * Both keys are 32-byte Buffers.
10
+ */
11
+ interface KeyPair {
12
+ /**
13
+ * Private key (32 bytes).
14
+ *
15
+ * **⚠️ KEEP THIS SECRET.** Never log, transmit, or store in plaintext.
16
+ */
17
+ readonly privateKey: Buffer;
18
+ /**
19
+ * Public key (32 bytes).
20
+ *
21
+ * Safe to share publicly.
22
+ */
23
+ readonly publicKey: Buffer;
24
+ }
25
+ /**
26
+ * A Curve25519 public key — type-tag for stronger typing.
27
+ *
28
+ * Use {@link asPublicKey} to brand a Buffer.
29
+ */
30
+ type PublicKey = Buffer & {
31
+ readonly __brand?: 'PublicKey';
32
+ };
33
+ /**
34
+ * A Curve25519 private key — type-tag for stronger typing.
35
+ *
36
+ * Use {@link asPrivateKey} to brand a Buffer.
37
+ */
38
+ type PrivateKey = Buffer & {
39
+ readonly __brand?: 'PrivateKey';
40
+ };
41
+ /**
42
+ * An X25519 ECDH shared secret (32 bytes).
43
+ *
44
+ * **⚠️ DO NOT USE DIRECTLY AS A KEY.** Always derive through HKDF.
45
+ */
46
+ type SharedSecret = Buffer & {
47
+ readonly __brand?: 'SharedSecret';
48
+ };
49
+ /**
50
+ * HKDF pseudorandom key (32 bytes), output of the Extract step.
51
+ */
52
+ type PseudoRandomKey = Buffer & {
53
+ readonly __brand?: 'PRK';
54
+ };
55
+ /**
56
+ * HKDF parameters object — useful for organizing key derivation calls.
57
+ */
58
+ interface HkdfParams {
59
+ /** Optional salt (use `Buffer.alloc(0)` if absent). */
60
+ salt: Buffer;
61
+ /** Input keying material (e.g., ECDH shared secret). */
62
+ ikm: Buffer;
63
+ /** Context-specific information (binds the output to a usage). */
64
+ info: Buffer;
65
+ /** Desired output length in bytes (1 to 8160). */
66
+ length: number;
67
+ }
68
+ /**
69
+ * AES-256-GCM parameters.
70
+ */
71
+ interface AesGcmParams {
72
+ /** 32-byte symmetric key. */
73
+ key: Buffer;
74
+ /** 12-byte nonce (MUST be unique per message). */
75
+ nonce: Buffer;
76
+ /** Plaintext or ciphertext. */
77
+ data: Buffer;
78
+ }
79
+ /**
80
+ * AES-256-CBC parameters.
81
+ */
82
+ interface AesCbcParams {
83
+ /** 32-byte symmetric key. */
84
+ key: Buffer;
85
+ /** 16-byte initialization vector. */
86
+ iv: Buffer;
87
+ /** Plaintext or ciphertext. */
88
+ data: Buffer;
89
+ }
90
+ /**
91
+ * Supported encodings for converting Buffers to/from strings.
92
+ */
93
+ type Encoding = 'hex' | 'base64' | 'base64url' | 'utf8' | 'binary';
94
+ /**
95
+ * Brand a Buffer as a {@link PublicKey}.
96
+ *
97
+ * Does NOT validate length — use validators separately.
98
+ */
99
+ declare function asPublicKey(buf: Buffer): PublicKey;
100
+ /**
101
+ * Brand a Buffer as a {@link PrivateKey}.
102
+ *
103
+ * Does NOT validate length — use validators separately.
104
+ */
105
+ declare function asPrivateKey(buf: Buffer): PrivateKey;
106
+ /**
107
+ * Brand a Buffer as a {@link SharedSecret}.
108
+ */
109
+ declare function asSharedSecret(buf: Buffer): SharedSecret;
110
+
111
+ /**
112
+ * Core cryptographic wrappers for signalis-core.
113
+ *
114
+ * Provides robust, validated, and well-documented APIs over the native Rust
115
+ * crypto primitives.
116
+ *
117
+ * @packageDocumentation
118
+ */
119
+
120
+ /**
121
+ * Curve25519 / X25519 elliptic curve operations.
122
+ *
123
+ * Provides:
124
+ * - Keypair generation
125
+ * - Public key derivation
126
+ * - ECDH key agreement
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * import { Curve25519 } from '@brashkie/signalis-core';
131
+ *
132
+ * const alice = Curve25519.generateKeyPair();
133
+ * const bob = Curve25519.generateKeyPair();
134
+ *
135
+ * const shared = Curve25519.diffieHellman(alice.privateKey, bob.publicKey);
136
+ * // ⚠️ Always derive via HKDF before use as a key!
137
+ * ```
138
+ */
139
+ declare const Curve25519: Readonly<{
140
+ /**
141
+ * Generate a new random Curve25519 keypair.
142
+ *
143
+ * Uses the OS's cryptographically secure RNG (via Rust's `OsRng`).
144
+ *
145
+ * @returns A {@link KeyPair} with private and public keys (32 bytes each)
146
+ */
147
+ generateKeyPair(): KeyPair;
148
+ /**
149
+ * Derive the public key corresponding to a given private key.
150
+ *
151
+ * @param privateKey - 32-byte private key
152
+ * @returns The corresponding 32-byte public key
153
+ * @throws {ValidationError} If `privateKey` is not a 32-byte Buffer.
154
+ */
155
+ publicFromPrivate(privateKey: Buffer): Buffer;
156
+ /**
157
+ * Perform X25519 Diffie-Hellman key agreement.
158
+ *
159
+ * Both parties run this with swapped (private, peer-public) arguments
160
+ * and obtain the same 32-byte shared secret.
161
+ *
162
+ * **⚠️ CRITICAL:** Do NOT use the returned secret directly as an
163
+ * encryption key. Always derive an actual key through HKDF:
164
+ *
165
+ * @example
166
+ * ```ts
167
+ * const shared = Curve25519.diffieHellman(myPriv, theirPub);
168
+ * const key = HKDF.derive(salt, shared, Buffer.from('aes-key'), 32);
169
+ * ```
170
+ *
171
+ * @param privateKey - Your 32-byte private key
172
+ * @param peerPublicKey - Peer's 32-byte public key
173
+ * @returns 32-byte shared secret
174
+ * @throws {ValidationError} If keys are not 32 bytes.
175
+ * @throws {CryptoError} If the operation fails.
176
+ */
177
+ diffieHellman(privateKey: Buffer, peerPublicKey: Buffer): Buffer;
178
+ /**
179
+ * The size of a Curve25519 private key in bytes (32).
180
+ */
181
+ PRIVATE_KEY_SIZE: 32;
182
+ /**
183
+ * The size of a Curve25519 public key in bytes (32).
184
+ */
185
+ PUBLIC_KEY_SIZE: 32;
186
+ /**
187
+ * The size of an X25519 shared secret in bytes (32).
188
+ */
189
+ SHARED_SECRET_SIZE: 32;
190
+ }>;
191
+ /**
192
+ * HKDF-SHA256 (RFC 5869) — HMAC-based Key Derivation Function.
193
+ *
194
+ * Provides cryptographic key derivation from high-entropy inputs (e.g., ECDH
195
+ * shared secrets) into arbitrary-length output keying material (OKM).
196
+ *
197
+ * @example
198
+ * ```ts
199
+ * // One-shot (recommended)
200
+ * const key = HKDF.derive(salt, sharedSecret, Buffer.from('aes-key'), 32);
201
+ *
202
+ * // Two-step (advanced)
203
+ * const prk = HKDF.extract(salt, ikm);
204
+ * const okm = HKDF.expand(prk, info, 64);
205
+ * ```
206
+ */
207
+ declare const HKDF: Readonly<{
208
+ /**
209
+ * HKDF-Extract: produces a 32-byte pseudorandom key (PRK).
210
+ *
211
+ * @param salt - Optional salt (pass `Buffer.alloc(0)` if not available)
212
+ * @param ikm - Input keying material
213
+ * @returns 32-byte PRK
214
+ * @throws {ValidationError} If inputs are not Buffers.
215
+ */
216
+ extract(salt: Buffer, ikm: Buffer): Buffer;
217
+ /**
218
+ * HKDF-Expand: produces `length` bytes of output keying material.
219
+ *
220
+ * @param prk - 32-byte pseudorandom key from {@link extract}
221
+ * @param info - Context-specific information (binds output to a usage)
222
+ * @param length - Desired output length (1 to 8160 bytes)
223
+ * @returns OKM of requested length
224
+ * @throws {ValidationError} If PRK is not 32 bytes or length is out of bounds.
225
+ */
226
+ expand(prk: Buffer, info: Buffer, length: number): Buffer;
227
+ /**
228
+ * HKDF one-shot: extract + expand in a single call.
229
+ *
230
+ * Use this whenever possible — it's the standard HKDF API.
231
+ *
232
+ * @param salt - Optional salt
233
+ * @param ikm - Input keying material
234
+ * @param info - Context info
235
+ * @param length - Desired output length
236
+ * @returns OKM of requested length
237
+ */
238
+ derive(salt: Buffer, ikm: Buffer, info: Buffer, length: number): Buffer;
239
+ /**
240
+ * Derive multiple keys from the same shared secret in a single call.
241
+ *
242
+ * Useful for deriving e.g., a send key AND a receive key simultaneously.
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * const [sendKey, recvKey] = HKDF.deriveMultiple(
247
+ * salt,
248
+ * sharedSecret,
249
+ * Buffer.from('signalis-channel-v1'),
250
+ * [32, 32],
251
+ * );
252
+ * ```
253
+ *
254
+ * @param salt - Optional salt
255
+ * @param ikm - Input keying material
256
+ * @param info - Context info
257
+ * @param lengths - Array of output lengths
258
+ * @returns Array of derived keys, one per requested length
259
+ */
260
+ deriveMultiple(salt: Buffer, ikm: Buffer, info: Buffer, lengths: number[]): Buffer[];
261
+ /**
262
+ * Derive a key using an {@link HkdfParams} object (alternative API).
263
+ */
264
+ deriveFromParams(params: HkdfParams): Buffer;
265
+ /**
266
+ * The size of an HKDF PRK in bytes (32).
267
+ */
268
+ PRK_SIZE: 32;
269
+ }>;
270
+ /**
271
+ * AES-256-GCM authenticated encryption (AEAD).
272
+ *
273
+ * Combines confidentiality + authenticity in a single primitive.
274
+ *
275
+ * **⚠️ CRITICAL SECURITY RULES:**
276
+ * 1. Never reuse a (key, nonce) pair. Catastrophic failure.
277
+ * 2. Generate nonces with `secureRandom(12)` for each message.
278
+ * 3. After 2^32 messages with random nonces, rotate the key.
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * import { AES_GCM, secureRandom } from '@brashkie/signalis-core';
283
+ *
284
+ * const key = secureRandom(32);
285
+ * const nonce = secureRandom(12);
286
+ * const plaintext = Buffer.from('Hello!');
287
+ *
288
+ * const ciphertext = AES_GCM.encrypt(key, nonce, plaintext);
289
+ * const decrypted = AES_GCM.decrypt(key, nonce, ciphertext);
290
+ * ```
291
+ */
292
+ declare const AES_GCM: Readonly<{
293
+ /**
294
+ * Encrypt plaintext.
295
+ *
296
+ * Returns: ciphertext || 16-byte authentication tag (concatenated).
297
+ *
298
+ * @param key - 32-byte symmetric key
299
+ * @param nonce - 12-byte unique nonce (NEVER reuse with same key)
300
+ * @param plaintext - Data to encrypt
301
+ * @returns Ciphertext + auth tag (output is `plaintext.length + 16` bytes)
302
+ * @throws {ValidationError} On invalid sizes.
303
+ * @throws {CryptoError} If the operation fails.
304
+ */
305
+ encrypt(key: Buffer, nonce: Buffer, plaintext: Buffer): Buffer;
306
+ /**
307
+ * Decrypt ciphertext and verify authentication tag.
308
+ *
309
+ * @param key - 32-byte symmetric key (same as encryption)
310
+ * @param nonce - 12-byte nonce (same as encryption)
311
+ * @param ciphertext - Ciphertext || auth tag
312
+ * @returns Original plaintext
313
+ * @throws {ValidationError} On invalid sizes.
314
+ * @throws {AuthenticationError} If the tag is invalid (tampered or wrong key).
315
+ */
316
+ decrypt(key: Buffer, nonce: Buffer, ciphertext: Buffer): Buffer;
317
+ /** Key size in bytes (32). */
318
+ KEY_SIZE: 32;
319
+ /** Nonce size in bytes (12). */
320
+ NONCE_SIZE: 12;
321
+ /** Tag size in bytes (16). */
322
+ TAG_SIZE: 16;
323
+ }>;
324
+ /**
325
+ * AES-256-CBC block cipher (NOT authenticated by itself).
326
+ *
327
+ * **⚠️ MUST be paired with HMAC** for integrity protection (encrypt-then-MAC).
328
+ *
329
+ * Prefer {@link AES_GCM} unless you need:
330
+ * - Legacy Signal Protocol media compatibility
331
+ * - Hardware that lacks GCM acceleration
332
+ */
333
+ declare const AES_CBC: Readonly<{
334
+ /**
335
+ * Encrypt with PKCS#7 padding.
336
+ *
337
+ * @param key - 32-byte symmetric key
338
+ * @param iv - 16-byte initialization vector
339
+ * @param plaintext - Data to encrypt
340
+ * @returns Ciphertext (padded to nearest 16-byte block)
341
+ */
342
+ encrypt(key: Buffer, iv: Buffer, plaintext: Buffer): Buffer;
343
+ /**
344
+ * Decrypt with PKCS#7 padding (no authentication).
345
+ *
346
+ * @param key - 32-byte symmetric key
347
+ * @param iv - 16-byte IV (same as encryption)
348
+ * @param ciphertext - Ciphertext
349
+ * @returns Original plaintext
350
+ * @throws {CryptoError} On padding errors.
351
+ */
352
+ decrypt(key: Buffer, iv: Buffer, ciphertext: Buffer): Buffer;
353
+ /** Key size in bytes (32). */
354
+ KEY_SIZE: 32;
355
+ /** IV size in bytes (16). */
356
+ IV_SIZE: 16;
357
+ }>;
358
+ /**
359
+ * HMAC-SHA256 message authentication code.
360
+ *
361
+ * Provides cryptographic authentication of arbitrary data with a shared key.
362
+ *
363
+ * @example
364
+ * ```ts
365
+ * const tag = HMAC.sha256(key, message);
366
+ * const valid = HMAC.verifySha256(key, message, tag); // constant-time
367
+ * ```
368
+ */
369
+ declare const HMAC: Readonly<{
370
+ /**
371
+ * Compute HMAC-SHA256 of `data` using `key`.
372
+ *
373
+ * @param key - Authentication key (any length)
374
+ * @param data - Data to authenticate
375
+ * @returns 32-byte HMAC tag
376
+ */
377
+ sha256(key: Buffer, data: Buffer): Buffer;
378
+ /**
379
+ * Verify an HMAC-SHA256 tag in **constant time**.
380
+ *
381
+ * Always use this instead of `===` to prevent timing attacks.
382
+ *
383
+ * @param key - Authentication key
384
+ * @param data - Original data
385
+ * @param expectedTag - Tag to verify
386
+ * @returns `true` if tag matches, `false` otherwise
387
+ */
388
+ verifySha256(key: Buffer, data: Buffer, expectedTag: Buffer): boolean;
389
+ /** Tag size in bytes (32). */
390
+ TAG_SIZE: 32;
391
+ }>;
392
+ /**
393
+ * SHA-256 cryptographic hash function.
394
+ *
395
+ * @example
396
+ * ```ts
397
+ * const digest = SHA256.hash(Buffer.from('hello'));
398
+ * ```
399
+ */
400
+ declare const SHA256: Readonly<{
401
+ /**
402
+ * Compute SHA-256 hash of `data`.
403
+ *
404
+ * @param data - Data to hash
405
+ * @returns 32-byte digest
406
+ */
407
+ hash(data: Buffer): Buffer;
408
+ /**
409
+ * Hash multiple Buffers concatenated together.
410
+ *
411
+ * Equivalent to `SHA256.hash(Buffer.concat([...]))` but slightly more
412
+ * efficient (avoids the intermediate concat).
413
+ */
414
+ hashAll(buffers: Buffer[]): Buffer;
415
+ /** Output size in bytes (32). */
416
+ OUTPUT_SIZE: 32;
417
+ }>;
418
+ /**
419
+ * The version of the underlying Rust crate (from `Cargo.toml`).
420
+ */
421
+ declare const nativeVersion: string;
422
+
423
+ /**
424
+ * Typed error classes for signalis-core.
425
+ *
426
+ * All errors extend the base `SignalisError` class for easy `instanceof` checks.
427
+ *
428
+ * @packageDocumentation
429
+ */
430
+ /**
431
+ * Base error class for all signalis-core errors.
432
+ *
433
+ * @example
434
+ * ```ts
435
+ * try {
436
+ * Curve25519.diffieHellman(invalidKey, peer);
437
+ * } catch (e) {
438
+ * if (e instanceof SignalisError) {
439
+ * console.error('Crypto error:', e.code, e.message);
440
+ * }
441
+ * }
442
+ * ```
443
+ */
444
+ declare class SignalisError extends Error {
445
+ /** Error code for programmatic handling. */
446
+ readonly code: string;
447
+ constructor(message: string, code: string);
448
+ }
449
+ /**
450
+ * Thrown when input validation fails (wrong size, wrong type, etc.).
451
+ */
452
+ declare class ValidationError extends SignalisError {
453
+ /** Name of the parameter that failed validation. */
454
+ readonly parameter?: string;
455
+ /** Expected value description. */
456
+ readonly expected?: string;
457
+ /** Actual value received. */
458
+ readonly actual?: string | number;
459
+ constructor(message: string, options?: {
460
+ parameter?: string;
461
+ expected?: string;
462
+ actual?: string | number;
463
+ });
464
+ }
465
+ /**
466
+ * Thrown when a crypto operation fails (decryption, MAC verification, etc.).
467
+ */
468
+ declare class CryptoError extends SignalisError {
469
+ /** The crypto operation that failed. */
470
+ readonly operation: string;
471
+ constructor(message: string, operation: string);
472
+ }
473
+ /**
474
+ * Thrown when AEAD authentication fails (e.g., AES-GCM tag mismatch).
475
+ *
476
+ * This is a security-critical error: the ciphertext was tampered with
477
+ * or the wrong key was used.
478
+ */
479
+ declare class AuthenticationError extends CryptoError {
480
+ constructor(message?: string);
481
+ }
482
+ /**
483
+ * Thrown when a key derivation or key agreement operation fails.
484
+ */
485
+ declare class KeyDerivationError extends CryptoError {
486
+ constructor(message: string);
487
+ }
488
+ /**
489
+ * Thrown when the requested output length is invalid (e.g., HKDF > 8160 bytes).
490
+ */
491
+ declare class LengthError extends ValidationError {
492
+ constructor(message: string, options?: {
493
+ expected?: string;
494
+ actual?: number;
495
+ });
496
+ }
497
+
498
+ /**
499
+ * Utility functions for signalis-core.
500
+ *
501
+ * Encoding helpers, secure random generation, and constant-time comparisons.
502
+ *
503
+ * @packageDocumentation
504
+ */
505
+
506
+ /**
507
+ * Generate cryptographically secure random bytes.
508
+ *
509
+ * Uses Node's `crypto.randomBytes` which delegates to the OS CSPRNG:
510
+ * - Linux/macOS: `getrandom()` / `/dev/urandom`
511
+ * - Windows: `BCryptGenRandom`
512
+ *
513
+ * @param length - Number of bytes to generate
514
+ * @returns A Buffer of `length` random bytes
515
+ *
516
+ * @example
517
+ * ```ts
518
+ * const nonce = secureRandom(12); // 12-byte nonce for AES-GCM
519
+ * const key = secureRandom(32); // 32-byte AES key
520
+ * ```
521
+ */
522
+ declare function secureRandom(length: number): Buffer;
523
+ /**
524
+ * Generate a cryptographically secure random 12-byte nonce (for AES-GCM).
525
+ */
526
+ declare function randomNonce(): Buffer;
527
+ /**
528
+ * Generate a cryptographically secure random 16-byte IV (for AES-CBC).
529
+ */
530
+ declare function randomIv(): Buffer;
531
+ /**
532
+ * Generate a cryptographically secure random 32-byte key.
533
+ */
534
+ declare function randomKey(): Buffer;
535
+ /**
536
+ * Convert a Buffer to its hexadecimal string representation.
537
+ *
538
+ * @example
539
+ * ```ts
540
+ * toHex(Buffer.from([0xff, 0x00])); // "ff00"
541
+ * ```
542
+ */
543
+ declare function toHex(buf: Buffer): string;
544
+ /**
545
+ * Parse a hexadecimal string into a Buffer.
546
+ *
547
+ * @throws {Error} If `hex` contains non-hex characters or has odd length.
548
+ */
549
+ declare function fromHex(hex: string): Buffer;
550
+ /**
551
+ * Convert a Buffer to a standard base64 string.
552
+ */
553
+ declare function toBase64(buf: Buffer): string;
554
+ /**
555
+ * Parse a base64 string into a Buffer.
556
+ */
557
+ declare function fromBase64(b64: string): Buffer;
558
+ /**
559
+ * Convert a Buffer to a URL-safe base64 string (no padding).
560
+ *
561
+ * Useful for URLs, query strings, JWT headers, etc.
562
+ */
563
+ declare function toBase64Url(buf: Buffer): string;
564
+ /**
565
+ * Parse a base64url string into a Buffer.
566
+ */
567
+ declare function fromBase64Url(b64url: string): Buffer;
568
+ /**
569
+ * Convert a Buffer to a string using the specified encoding.
570
+ */
571
+ declare function bufferToString(buf: Buffer, encoding?: Encoding): string;
572
+ /**
573
+ * Parse a string into a Buffer using the specified encoding.
574
+ */
575
+ declare function stringToBuffer(str: string, encoding?: Encoding): Buffer;
576
+ /**
577
+ * Compare two Buffers in constant time (resistant to timing attacks).
578
+ *
579
+ * **Always** use this instead of `===` or `Buffer.equals` when comparing
580
+ * MACs, signatures, or any other security-sensitive bytes.
581
+ *
582
+ * Returns `false` if lengths differ (without revealing the difference).
583
+ *
584
+ * @example
585
+ * ```ts
586
+ * const valid = constantTimeEqual(receivedTag, expectedTag);
587
+ * if (!valid) throw new Error('MAC verification failed');
588
+ * ```
589
+ */
590
+ declare function constantTimeEqual(a: Buffer, b: Buffer): boolean;
591
+ /**
592
+ * Concatenate multiple Buffers into one.
593
+ *
594
+ * Thin wrapper over `Buffer.concat` with cleaner naming.
595
+ */
596
+ declare function concat(buffers: Buffer[]): Buffer;
597
+ /**
598
+ * Zero out a Buffer in-place.
599
+ *
600
+ * Useful for clearing sensitive data after use.
601
+ *
602
+ * **Note:** JavaScript runtimes may keep copies in GC buffers, so this is
603
+ * NOT a guaranteed wipe. For real security, use Rust-side zeroization.
604
+ */
605
+ declare function zeroize(buf: Buffer): void;
606
+ /**
607
+ * XOR two equal-length Buffers and return the result.
608
+ *
609
+ * @throws {Error} If buffers have different lengths.
610
+ */
611
+ declare function xor(a: Buffer, b: Buffer): Buffer;
612
+
613
+ /**
614
+ * Input validators for signalis-core.
615
+ *
616
+ * All validators throw `ValidationError` with detailed information.
617
+ *
618
+ * @packageDocumentation
619
+ */
620
+ /**
621
+ * Assert that a value is a `Buffer`.
622
+ *
623
+ * @throws {ValidationError} If `value` is not a Buffer.
624
+ */
625
+ declare function assertBuffer(value: unknown, parameter: string): asserts value is Buffer;
626
+ /**
627
+ * Assert that a Buffer has exactly the expected length.
628
+ *
629
+ * @throws {ValidationError} If length mismatch.
630
+ */
631
+ declare function assertBufferLength(value: Buffer, expectedLength: number, parameter: string): void;
632
+ /**
633
+ * Combined check: must be a Buffer of exactly N bytes.
634
+ */
635
+ declare function assertBufferOfSize(value: unknown, expectedLength: number, parameter: string): asserts value is Buffer;
636
+ /**
637
+ * Assert that a number is a positive integer.
638
+ */
639
+ declare function assertPositiveInteger(value: unknown, parameter: string): asserts value is number;
640
+ /**
641
+ * Assert HKDF output length is within bounds.
642
+ */
643
+ declare function assertHkdfLength(length: unknown): asserts length is number;
644
+ /**
645
+ * Check if two Buffers have the same length (utility for tests).
646
+ */
647
+ declare function buffersSameLength(a: Buffer, b: Buffer): boolean;
648
+
649
+ /**
650
+ * Public constants used throughout signalis-core.
651
+ *
652
+ * @packageDocumentation
653
+ */
654
+ /** Size of a Curve25519 private key in bytes. */
655
+ declare const CURVE25519_PRIVATE_KEY_SIZE = 32;
656
+ /** Size of a Curve25519 public key in bytes. */
657
+ declare const CURVE25519_PUBLIC_KEY_SIZE = 32;
658
+ /** Size of an X25519 ECDH shared secret in bytes. */
659
+ declare const CURVE25519_SHARED_SECRET_SIZE = 32;
660
+ /** Size of HKDF-SHA256 PRK (pseudorandom key) in bytes. */
661
+ declare const HKDF_PRK_SIZE = 32;
662
+ /** Maximum HKDF-SHA256 output length: 255 * HashLen = 255 * 32 = 8160 bytes. */
663
+ declare const HKDF_MAX_OUTPUT_SIZE = 8160;
664
+ /** Size of an AES-256 key in bytes. */
665
+ declare const AES_256_KEY_SIZE = 32;
666
+ /** Size of an AES-256-GCM nonce in bytes (recommended size per NIST SP 800-38D). */
667
+ declare const AES_256_GCM_NONCE_SIZE = 12;
668
+ /** Size of an AES-256-GCM authentication tag in bytes. */
669
+ declare const AES_256_GCM_TAG_SIZE = 16;
670
+ /** Size of an AES-256-CBC IV in bytes (one AES block). */
671
+ declare const AES_256_CBC_IV_SIZE = 16;
672
+ /** AES block size in bytes. */
673
+ declare const AES_BLOCK_SIZE = 16;
674
+ /** Size of a SHA-256 hash output in bytes. */
675
+ declare const SHA256_OUTPUT_SIZE = 32;
676
+ /** Size of an HMAC-SHA256 tag in bytes. */
677
+ declare const HMAC_SHA256_TAG_SIZE = 32;
678
+ /** SHA-256 block size (used internally by HMAC). */
679
+ declare const SHA256_BLOCK_SIZE = 64;
680
+ /**
681
+ * Maximum recommended plaintext size for AES-GCM (~64 GiB).
682
+ *
683
+ * AES-GCM has a hard limit of 2^39 - 256 bits ≈ 64 GiB per single encryption
684
+ * under the same key+nonce. We recommend much smaller messages and key rotation.
685
+ */
686
+ declare const AES_GCM_MAX_PLAINTEXT_SIZE: number;
687
+ /**
688
+ * Recommended maximum number of messages encrypted under the same AES-GCM key
689
+ * with random 96-bit nonces before key rotation: 2^32.
690
+ */
691
+ declare const AES_GCM_RECOMMENDED_MESSAGES_PER_KEY = 4294967296;
692
+
693
+ /**
694
+ * The version of `@brashkie/signalis-core` (matches `package.json`).
695
+ *
696
+ * Bumped on every release.
697
+ */
698
+ declare const VERSION: "0.1.0";
699
+
700
+ /**
701
+ * Default export — provides all primitives and helpers under one namespace.
702
+ *
703
+ * @example
704
+ * ```ts
705
+ * import sc from '@brashkie/signalis-core';
706
+ *
707
+ * const kp = sc.Curve25519.generateKeyPair();
708
+ * const nonce = sc.secureRandom(12);
709
+ * ```
710
+ */
711
+ declare const SignalisCore: Readonly<{
712
+ Curve25519: Readonly<{
713
+ generateKeyPair(): KeyPair;
714
+ publicFromPrivate(privateKey: Buffer): Buffer;
715
+ diffieHellman(privateKey: Buffer, peerPublicKey: Buffer): Buffer;
716
+ PRIVATE_KEY_SIZE: 32;
717
+ PUBLIC_KEY_SIZE: 32;
718
+ SHARED_SECRET_SIZE: 32;
719
+ }>;
720
+ HKDF: Readonly<{
721
+ extract(salt: Buffer, ikm: Buffer): Buffer;
722
+ expand(prk: Buffer, info: Buffer, length: number): Buffer;
723
+ derive(salt: Buffer, ikm: Buffer, info: Buffer, length: number): Buffer;
724
+ deriveMultiple(salt: Buffer, ikm: Buffer, info: Buffer, lengths: number[]): Buffer[];
725
+ deriveFromParams(params: HkdfParams): Buffer;
726
+ PRK_SIZE: 32;
727
+ }>;
728
+ AES_GCM: Readonly<{
729
+ encrypt(key: Buffer, nonce: Buffer, plaintext: Buffer): Buffer;
730
+ decrypt(key: Buffer, nonce: Buffer, ciphertext: Buffer): Buffer;
731
+ KEY_SIZE: 32;
732
+ NONCE_SIZE: 12;
733
+ TAG_SIZE: 16;
734
+ }>;
735
+ AES_CBC: Readonly<{
736
+ encrypt(key: Buffer, iv: Buffer, plaintext: Buffer): Buffer;
737
+ decrypt(key: Buffer, iv: Buffer, ciphertext: Buffer): Buffer;
738
+ KEY_SIZE: 32;
739
+ IV_SIZE: 16;
740
+ }>;
741
+ HMAC: Readonly<{
742
+ sha256(key: Buffer, data: Buffer): Buffer;
743
+ verifySha256(key: Buffer, data: Buffer, expectedTag: Buffer): boolean;
744
+ TAG_SIZE: 32;
745
+ }>;
746
+ SHA256: Readonly<{
747
+ hash(data: Buffer): Buffer;
748
+ hashAll(buffers: Buffer[]): Buffer;
749
+ OUTPUT_SIZE: 32;
750
+ }>;
751
+ secureRandom: typeof secureRandom;
752
+ randomNonce: typeof randomNonce;
753
+ randomIv: typeof randomIv;
754
+ randomKey: typeof randomKey;
755
+ toHex: typeof toHex;
756
+ fromHex: typeof fromHex;
757
+ toBase64: typeof toBase64;
758
+ fromBase64: typeof fromBase64;
759
+ constantTimeEqual: typeof constantTimeEqual;
760
+ VERSION: "0.1.0";
761
+ nativeVersion: string;
762
+ }>;
763
+
764
+ export { AES_256_CBC_IV_SIZE, AES_256_GCM_NONCE_SIZE, AES_256_GCM_TAG_SIZE, AES_256_KEY_SIZE, AES_BLOCK_SIZE, AES_CBC, AES_GCM, AES_GCM_MAX_PLAINTEXT_SIZE, AES_GCM_RECOMMENDED_MESSAGES_PER_KEY, type AesCbcParams, type AesGcmParams, AuthenticationError, CURVE25519_PRIVATE_KEY_SIZE, CURVE25519_PUBLIC_KEY_SIZE, CURVE25519_SHARED_SECRET_SIZE, CryptoError, Curve25519, type Encoding, HKDF, HKDF_MAX_OUTPUT_SIZE, HKDF_PRK_SIZE, HMAC, HMAC_SHA256_TAG_SIZE, type HkdfParams, KeyDerivationError, type KeyPair, LengthError, type PrivateKey, type PseudoRandomKey, type PublicKey, SHA256, SHA256_BLOCK_SIZE, SHA256_OUTPUT_SIZE, type SharedSecret, SignalisError, VERSION, ValidationError, asPrivateKey, asPublicKey, asSharedSecret, assertBuffer, assertBufferLength, assertBufferOfSize, assertHkdfLength, assertPositiveInteger, bufferToString, buffersSameLength, concat, constantTimeEqual, SignalisCore as default, fromBase64, fromBase64Url, fromHex, nativeVersion, randomIv, randomKey, randomNonce, secureRandom, stringToBuffer, toBase64, toBase64Url, toHex, xor, zeroize };