@crossdyne/security 0.3.1-beta.1 → 0.5.0-beta.1

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.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ type HashAlgorithm = 'SHA-256' | 'SHA-384' | 'SHA-512';
2
+
1
3
  declare const SecurityConstants: {
2
4
  readonly AesGcmNonceSize: 12;
3
5
  readonly AesGcmTagSize: 16;
@@ -8,38 +10,16 @@ declare const SecurityConstants: {
8
10
  readonly Pbkdf2IterationsMinimum: 100000;
9
11
  };
10
12
 
11
- type HashAlgorithm = 'SHA-256' | 'SHA-384' | 'SHA-512';
12
-
13
13
  declare const SupportedHashAlgorithms: ReadonlyArray<HashAlgorithm>;
14
14
 
15
15
  /**
16
- * AES-GCM encryption options: nonce size, tag size, and optional AAD.
17
- * Mutable builder-style; call {@link build} to validate.
16
+ * Supported cryptographic profile versions.
17
+ * V1: baseline (PBKDF2-HMAC-SHA256, AES-256-GCM, 12-byte nonce, 16-byte tag).
18
+ * Append new members sequentially; never change existing values.
18
19
  */
19
- declare class AesGcmOptions {
20
- private _nonceSize;
21
- private _tagSize;
22
- /** Optional Additional Authenticated Data (not encrypted). */
23
- associatedData?: Uint8Array;
24
- /** Nonce size in bytes (must be 12). */
25
- get nonceSize(): number;
26
- set nonceSize(v: number);
27
- /** Tag size in bytes (12–16, default 16). */
28
- get tagSize(): number;
29
- set tagSize(v: number);
30
- /** Validates that {@link tagSize} is in the allowed range. */
31
- validate(): void;
32
- /** Default preset: nonce=12, tag=16, no AAD. */
33
- static get default(): AesGcmOptions;
34
- /** Fluent setter for {@link tagSize}. */
35
- withTagSize(s: number): this;
36
- /**
37
- * Fluent setter for {@link associatedData}.
38
- * Accepts a byte array or a UTF-8 string (encoded internally).
39
- */
40
- withAssociatedData(aad: Uint8Array | string | undefined): this;
41
- /** Validates and returns this instance. */
42
- build(): AesGcmOptions;
20
+ declare enum CryptoVersion {
21
+ /** Version 1 — initial profile. */
22
+ V1 = 1
43
23
  }
44
24
 
45
25
  /**
@@ -54,7 +34,7 @@ declare class CryptoService {
54
34
  * @param options - AES-GCM configuration; uses default if omitted.
55
35
  * @returns Base64-encoded ciphertext with prepended nonce.
56
36
  */
57
- encryptData<T>(dataModel: T, key: Uint8Array, options?: AesGcmOptions): Promise<string>;
37
+ encryptData<T>(dataModel: T, key: Uint8Array, version?: CryptoVersion): Promise<string>;
58
38
  /**
59
39
  * Decrypts a Base64-encoded ciphertext back to the original object.
60
40
  * @param encryptedBase64 - The encrypted data.
@@ -63,7 +43,7 @@ declare class CryptoService {
63
43
  * @returns Deserialized object, or null if input is empty.
64
44
  * @throws If authentication tag mismatch or corrupted data.
65
45
  */
66
- decryptData<T>(encryptedBase64: string, key: Uint8Array, options?: AesGcmOptions, isBytes?: boolean): Promise<T | null>;
46
+ decryptData<T>(encryptedBase64: string, key: Uint8Array, isBytes?: boolean): Promise<T | null>;
67
47
  /**
68
48
  * Generates cryptographically secure random bytes.
69
49
  * @param length - Number of bytes (default 32).
@@ -72,49 +52,28 @@ declare class CryptoService {
72
52
  generateRandomBytes: (length?: number) => Uint8Array;
73
53
  }
74
54
 
75
- /**
76
- * PBKDF2 key derivation options: iterations count and hash algorithm.
77
- * Mutable builder-style; call {@link build} to validate.
78
- */
79
- declare class KdfOptions {
80
- private _pbkdf2Iterations;
81
- private _hashAlgorithm;
82
- /** PBKDF2 iteration count (minimum 100_000). */
83
- get pbkdf2Iterations(): number;
84
- set pbkdf2Iterations(v: number);
85
- /** Hash algorithm used by PBKDF2. Must be one of {@link SupportedHashAlgorithms}. */
86
- get hashAlgorithm(): HashAlgorithm;
87
- set hashAlgorithm(v: HashAlgorithm);
88
- /** Validates iterations and hash algorithm. */
89
- validate(): void;
90
- /** Default preset: SHA-256, 600_000 iterations. */
91
- static get default(): KdfOptions;
92
- /** Fluent setter for {@link pbkdf2Iterations}. */
93
- withPbkdf2Iterations(i: number): this;
94
- /** Fluent setter for {@link hashAlgorithm}. */
95
- withHashAlgorithm(h: HashAlgorithm): this;
96
- /** Validates and returns this instance. */
97
- build(): KdfOptions;
98
- }
99
-
100
55
  /**
101
56
  * Two-stage key derivation: PBKDF2 (master key) → HKDF (sub-keys).
102
57
  */
103
58
  declare class KeyDerivationService {
104
59
  /**
105
- * Derives KEK and Base64 AuthHash. Identity is normalized (trimmed, lowercase).
60
+ * Derives KEK and Base64 AuthHash. Identity is hashed as-is — caller must
61
+ * normalize (trim, lowercase, etc.) before calling.
62
+ * @param identity - User identity (pre-normalized by caller).
106
63
  * @param identity - User identity (email, username).
107
64
  * @param password - User password.
108
65
  * @param salt - Random salt.
109
66
  * @param options - KDF configuration; uses default if omitted.
110
67
  * @returns Object with `kek` (Uint8Array) and `authHash` (Base64 string).
111
68
  */
112
- deriveKeysFromPassword(identity: string, password: string, salt: Uint8Array, options?: KdfOptions): Promise<{
69
+ deriveKeysFromPassword(identity: string, password: string, salt: Uint8Array, version: CryptoVersion): Promise<{
113
70
  kek: Uint8Array;
114
71
  authHash: string;
115
72
  }>;
116
73
  /**
117
74
  * Derives an SRP-compatible authentication hash (output size = hash output length).
75
+ * Identity is hashed as-is — caller must normalize (trim, lowercase, etc.) before calling.
76
+ * @param identity - User identity (pre-normalized by caller).
118
77
  * @param identity - User identity.
119
78
  * @param password - User password.
120
79
  * @param salt - Random salt.
@@ -122,17 +81,62 @@ declare class KeyDerivationService {
122
81
  * @param options - KDF configuration; uses default if omitted.
123
82
  * @returns Raw hash bytes for use as SRP verifier input (x).
124
83
  */
125
- deriveAuthHashForSrp(identity: string, password: string, salt: Uint8Array, srpHashAlgorithm: HashAlgorithm, options?: KdfOptions): Promise<Uint8Array>;
84
+ deriveAuthHashForSrp(identity: string, password: string, salt: Uint8Array, srpHashAlgorithm: HashAlgorithm, version: CryptoVersion): Promise<Uint8Array>;
126
85
  }
127
86
 
128
87
  /**
129
- * Supported cryptographic profile versions.
130
- * V1: baseline (PBKDF2-HMAC-SHA256, AES-256-GCM, 12-byte nonce, 16-byte tag).
131
- * Append new members sequentially; never change existing values.
88
+ * AES-GCM encryption options: nonce size, tag size, and optional AAD.
89
+ * Mutable builder-style; call {@link build} to validate.
132
90
  */
133
- declare enum CryptoVersion {
134
- /** Version 1 — initial profile. */
135
- V1 = 1
91
+ declare class AesGcmOptions {
92
+ private _nonceSize;
93
+ private _tagSize;
94
+ /** Optional Additional Authenticated Data (not encrypted). */
95
+ associatedData?: Uint8Array;
96
+ /** Nonce size in bytes (must be 12). */
97
+ get nonceSize(): number;
98
+ set nonceSize(v: number);
99
+ /** Tag size in bytes (12–16, default 16). */
100
+ get tagSize(): number;
101
+ set tagSize(v: number);
102
+ /** Validates that {@link tagSize} is in the allowed range. */
103
+ validate(): void;
104
+ /** Default preset: nonce=12, tag=16, no AAD. */
105
+ static get default(): AesGcmOptions;
106
+ /** Fluent setter for {@link tagSize}. */
107
+ withTagSize(s: number): this;
108
+ /**
109
+ * Fluent setter for {@link associatedData}.
110
+ * Accepts a byte array or a UTF-8 string (encoded internally).
111
+ */
112
+ withAssociatedData(aad: Uint8Array | string | undefined): this;
113
+ /** Validates and returns this instance. */
114
+ build(): AesGcmOptions;
115
+ }
116
+
117
+ /**
118
+ * PBKDF2 key derivation options: iterations count and hash algorithm.
119
+ * Mutable builder-style; call {@link build} to validate.
120
+ */
121
+ declare class KdfOptions {
122
+ private _pbkdf2Iterations;
123
+ private _hashAlgorithm;
124
+ /** PBKDF2 iteration count (minimum 100_000). */
125
+ get pbkdf2Iterations(): number;
126
+ set pbkdf2Iterations(v: number);
127
+ /** Hash algorithm used by PBKDF2. Must be one of {@link SupportedHashAlgorithms}. */
128
+ get hashAlgorithm(): HashAlgorithm;
129
+ set hashAlgorithm(v: HashAlgorithm);
130
+ /** Validates iterations and hash algorithm. */
131
+ validate(): void;
132
+ /** Default preset: SHA-256, 600_000 iterations. */
133
+ static get default(): KdfOptions;
134
+ /** Fluent setter for {@link pbkdf2Iterations}. */
135
+ withPbkdf2Iterations(i: number): this;
136
+ /** Fluent setter for {@link hashAlgorithm}. */
137
+ withHashAlgorithm(h: HashAlgorithm): this;
138
+ /** Validates and returns this instance. */
139
+ build(): KdfOptions;
136
140
  }
137
141
 
138
142
  /**
@@ -201,15 +205,15 @@ declare class SrpClientService {
201
205
  * Generates client proof (A, M1, session key S) from server challenge.
202
206
  * @param login - User login.
203
207
  * @param password - Plaintext password.
204
- * @param saltBase64 - Server salt (URL-safe Base64).
205
- * @param B_base64 - Server public ephemeral B (URL-safe Base64).
208
+ * @param saltBase64 - Server salt (standard Base64).
209
+ * @param B_base64 - Server public ephemeral B (standard Base64).
206
210
  * @param ctx - SRP context.
207
- * @returns Object with A, M1, S as Base64 strings.
211
+ * @returns Object with A and M1 as standard Base64; SessionKeyK as raw bytes.
208
212
  */
209
- generateSrpProof(login: string, password: string, saltBase64: string, B_base64: string, ctx: SrpContext): Promise<{
213
+ generateSrpProof(login: string, password: string, saltBase64: string, B_base64: string, ctx: SrpContext, version: CryptoVersion): Promise<{
210
214
  A: string;
211
215
  M1: string;
212
- S: string;
216
+ SessionKeyK: Uint8Array;
213
217
  }>;
214
218
  /**
215
219
  * Validates the server proof M2 to authenticate the server.
@@ -220,7 +224,7 @@ declare class SrpClientService {
220
224
  * @param ctx - SRP context.
221
225
  * @returns True if the server proof is valid.
222
226
  */
223
- verifyServerM2(A_b64: string, M1_b64: string, S_b64: string, serverM2_b64: string, ctx: SrpContext): Promise<boolean>;
227
+ verifyServerM2(A_b64: string, M1_b64: string, sessionKeyK: Uint8Array, serverM2_b64: string, ctx: SrpContext): Promise<boolean>;
224
228
  }
225
229
 
226
230
  /**
@@ -230,11 +234,13 @@ interface SrpSessionState {
230
234
  /** User login identifier. */
231
235
  login: string;
232
236
  /** Server private ephemeral key (Base64). */
233
- privateKeyB: string;
237
+ privateKeyB: Uint8Array;
234
238
  /** Password verifier (Base64). */
235
- verifier: string;
239
+ verifier: Uint8Array;
236
240
  /** Server public ephemeral key B (Base64). */
237
- publicKeyB: string;
241
+ publicKeyB: Uint8Array;
242
+ /** User salt s (needed for RFC 5054 M1). */
243
+ salt: Uint8Array;
238
244
  }
239
245
  /**
240
246
  * Server-side SRP-6a: challenge generation, client proof verification, server proof creation.
@@ -247,7 +253,7 @@ declare class SrpServerService {
247
253
  * @param ctx - SRP context (hash, N, g, etc.).
248
254
  * @returns Session state with private b, verifier, and public B.
249
255
  */
250
- getSrpChallenge(login: string, verifierBytes: Uint8Array, ctx: SrpContext): Promise<SrpSessionState>;
256
+ getSrpChallenge(login: string, verifierBytes: Uint8Array, salt: Uint8Array, ctx: SrpContext): Promise<SrpSessionState>;
251
257
  /**
252
258
  * Verifies client M1 proof and returns server M2 proof.
253
259
  * @param sessionState - Server session state.
@@ -350,12 +356,13 @@ declare class SecurityUtils {
350
356
  static fromBase64(base64: string): Uint8Array;
351
357
  /** Converts big-endian bytes to bigint. */
352
358
  static bytesToBigInt(bytes: Uint8Array): bigint;
353
- /** Converts bigint to fixed-length big-endian bytes (pads/truncates). */
359
+ /** Converts bigint to fixed-length big-endian bytes (pads only; never truncates). */
354
360
  static bigIntToFixedBytes(bn: bigint, length: number): Uint8Array;
355
361
  /** Constant-time comparison of two Uint8Arrays. */
356
362
  static fixedTimeEquals(a: Uint8Array, b: Uint8Array): boolean;
357
363
  /** Modular exponentiation (base^exp mod mod) using binary exponentiation. */
358
364
  static expMod(base: bigint, exp: bigint, mod: bigint): bigint;
365
+ static bigIntToRawBytes(bn: bigint): Uint8Array;
359
366
  }
360
367
 
361
368
  /**
@@ -368,12 +375,30 @@ declare class SrpEncoding {
368
375
  static toHashBytes(ctx: SrpContext, value: bigint): Uint8Array;
369
376
  /** Hashes modulus-sized values (e.g., u = H(A, B)). */
370
377
  static hashModuli(ctx: SrpContext, ...values: bigint[]): Promise<bigint>;
371
- /** Computes M1 = H(A || B || sessionKeyK). */
372
- static computeM1(ctx: SrpContext, A: bigint, B: bigint, sessionKeyK: Uint8Array): Promise<bigint>;
378
+ /**
379
+ * Computes the client proof M1 = H( H(N) ⊕ H(g) | H(I) | s | PAD(A) | PAD(B) | K ).
380
+ *
381
+ * Follows RFC 5054 / SRP-6a:
382
+ * - H(N) and H(g) are hashed as modulus-sized values.
383
+ * - Identity (I) is hashed as raw UTF-8 bytes.
384
+ * - A and B are padded to the modulus size before hashing.
385
+ * - K is the session key (H(S) without padding).
386
+ *
387
+ * @param ctx - SRP context containing N, g, hash algorithm, and modulus size.
388
+ * @param A - Client ephemeral public key.
389
+ * @param B - Server ephemeral public key.
390
+ * @param sessionKeyK - Session key K as raw bytes.
391
+ * @param identity - User identity (login). Must be pre-normalized by the caller.
392
+ * @param salt - User-specific salt bytes.
393
+ * @returns The M1 proof as raw hash bytes.
394
+ */
395
+ static computeM1(ctx: SrpContext, A: bigint, B: bigint, sessionKeyK: Uint8Array, identity: string, salt: Uint8Array): Promise<Uint8Array>;
373
396
  /** Computes M2 = H(A || M1 || sessionKeyK). */
374
- static computeM2(ctx: SrpContext, A: bigint, M1: bigint, sessionKeyK: Uint8Array): Promise<bigint>;
397
+ static computeM2(ctx: SrpContext, A: bigint, m1Bytes: Uint8Array, sessionKeyK: Uint8Array): Promise<Uint8Array>;
375
398
  /** Computes session key K = H(S). */
376
399
  static computeSessionKey(ctx: SrpContext, S: bigint): Promise<Uint8Array>;
400
+ /** Hashes bytes and returns raw Uint8Array (для M1/M2). */
401
+ private static computeHash;
377
402
  /** Concatenates byte arrays and returns the hash as bigint. */
378
403
  private static hash;
379
404
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ type HashAlgorithm = 'SHA-256' | 'SHA-384' | 'SHA-512';
2
+
1
3
  declare const SecurityConstants: {
2
4
  readonly AesGcmNonceSize: 12;
3
5
  readonly AesGcmTagSize: 16;
@@ -8,38 +10,16 @@ declare const SecurityConstants: {
8
10
  readonly Pbkdf2IterationsMinimum: 100000;
9
11
  };
10
12
 
11
- type HashAlgorithm = 'SHA-256' | 'SHA-384' | 'SHA-512';
12
-
13
13
  declare const SupportedHashAlgorithms: ReadonlyArray<HashAlgorithm>;
14
14
 
15
15
  /**
16
- * AES-GCM encryption options: nonce size, tag size, and optional AAD.
17
- * Mutable builder-style; call {@link build} to validate.
16
+ * Supported cryptographic profile versions.
17
+ * V1: baseline (PBKDF2-HMAC-SHA256, AES-256-GCM, 12-byte nonce, 16-byte tag).
18
+ * Append new members sequentially; never change existing values.
18
19
  */
19
- declare class AesGcmOptions {
20
- private _nonceSize;
21
- private _tagSize;
22
- /** Optional Additional Authenticated Data (not encrypted). */
23
- associatedData?: Uint8Array;
24
- /** Nonce size in bytes (must be 12). */
25
- get nonceSize(): number;
26
- set nonceSize(v: number);
27
- /** Tag size in bytes (12–16, default 16). */
28
- get tagSize(): number;
29
- set tagSize(v: number);
30
- /** Validates that {@link tagSize} is in the allowed range. */
31
- validate(): void;
32
- /** Default preset: nonce=12, tag=16, no AAD. */
33
- static get default(): AesGcmOptions;
34
- /** Fluent setter for {@link tagSize}. */
35
- withTagSize(s: number): this;
36
- /**
37
- * Fluent setter for {@link associatedData}.
38
- * Accepts a byte array or a UTF-8 string (encoded internally).
39
- */
40
- withAssociatedData(aad: Uint8Array | string | undefined): this;
41
- /** Validates and returns this instance. */
42
- build(): AesGcmOptions;
20
+ declare enum CryptoVersion {
21
+ /** Version 1 — initial profile. */
22
+ V1 = 1
43
23
  }
44
24
 
45
25
  /**
@@ -54,7 +34,7 @@ declare class CryptoService {
54
34
  * @param options - AES-GCM configuration; uses default if omitted.
55
35
  * @returns Base64-encoded ciphertext with prepended nonce.
56
36
  */
57
- encryptData<T>(dataModel: T, key: Uint8Array, options?: AesGcmOptions): Promise<string>;
37
+ encryptData<T>(dataModel: T, key: Uint8Array, version?: CryptoVersion): Promise<string>;
58
38
  /**
59
39
  * Decrypts a Base64-encoded ciphertext back to the original object.
60
40
  * @param encryptedBase64 - The encrypted data.
@@ -63,7 +43,7 @@ declare class CryptoService {
63
43
  * @returns Deserialized object, or null if input is empty.
64
44
  * @throws If authentication tag mismatch or corrupted data.
65
45
  */
66
- decryptData<T>(encryptedBase64: string, key: Uint8Array, options?: AesGcmOptions, isBytes?: boolean): Promise<T | null>;
46
+ decryptData<T>(encryptedBase64: string, key: Uint8Array, isBytes?: boolean): Promise<T | null>;
67
47
  /**
68
48
  * Generates cryptographically secure random bytes.
69
49
  * @param length - Number of bytes (default 32).
@@ -72,49 +52,28 @@ declare class CryptoService {
72
52
  generateRandomBytes: (length?: number) => Uint8Array;
73
53
  }
74
54
 
75
- /**
76
- * PBKDF2 key derivation options: iterations count and hash algorithm.
77
- * Mutable builder-style; call {@link build} to validate.
78
- */
79
- declare class KdfOptions {
80
- private _pbkdf2Iterations;
81
- private _hashAlgorithm;
82
- /** PBKDF2 iteration count (minimum 100_000). */
83
- get pbkdf2Iterations(): number;
84
- set pbkdf2Iterations(v: number);
85
- /** Hash algorithm used by PBKDF2. Must be one of {@link SupportedHashAlgorithms}. */
86
- get hashAlgorithm(): HashAlgorithm;
87
- set hashAlgorithm(v: HashAlgorithm);
88
- /** Validates iterations and hash algorithm. */
89
- validate(): void;
90
- /** Default preset: SHA-256, 600_000 iterations. */
91
- static get default(): KdfOptions;
92
- /** Fluent setter for {@link pbkdf2Iterations}. */
93
- withPbkdf2Iterations(i: number): this;
94
- /** Fluent setter for {@link hashAlgorithm}. */
95
- withHashAlgorithm(h: HashAlgorithm): this;
96
- /** Validates and returns this instance. */
97
- build(): KdfOptions;
98
- }
99
-
100
55
  /**
101
56
  * Two-stage key derivation: PBKDF2 (master key) → HKDF (sub-keys).
102
57
  */
103
58
  declare class KeyDerivationService {
104
59
  /**
105
- * Derives KEK and Base64 AuthHash. Identity is normalized (trimmed, lowercase).
60
+ * Derives KEK and Base64 AuthHash. Identity is hashed as-is — caller must
61
+ * normalize (trim, lowercase, etc.) before calling.
62
+ * @param identity - User identity (pre-normalized by caller).
106
63
  * @param identity - User identity (email, username).
107
64
  * @param password - User password.
108
65
  * @param salt - Random salt.
109
66
  * @param options - KDF configuration; uses default if omitted.
110
67
  * @returns Object with `kek` (Uint8Array) and `authHash` (Base64 string).
111
68
  */
112
- deriveKeysFromPassword(identity: string, password: string, salt: Uint8Array, options?: KdfOptions): Promise<{
69
+ deriveKeysFromPassword(identity: string, password: string, salt: Uint8Array, version: CryptoVersion): Promise<{
113
70
  kek: Uint8Array;
114
71
  authHash: string;
115
72
  }>;
116
73
  /**
117
74
  * Derives an SRP-compatible authentication hash (output size = hash output length).
75
+ * Identity is hashed as-is — caller must normalize (trim, lowercase, etc.) before calling.
76
+ * @param identity - User identity (pre-normalized by caller).
118
77
  * @param identity - User identity.
119
78
  * @param password - User password.
120
79
  * @param salt - Random salt.
@@ -122,17 +81,62 @@ declare class KeyDerivationService {
122
81
  * @param options - KDF configuration; uses default if omitted.
123
82
  * @returns Raw hash bytes for use as SRP verifier input (x).
124
83
  */
125
- deriveAuthHashForSrp(identity: string, password: string, salt: Uint8Array, srpHashAlgorithm: HashAlgorithm, options?: KdfOptions): Promise<Uint8Array>;
84
+ deriveAuthHashForSrp(identity: string, password: string, salt: Uint8Array, srpHashAlgorithm: HashAlgorithm, version: CryptoVersion): Promise<Uint8Array>;
126
85
  }
127
86
 
128
87
  /**
129
- * Supported cryptographic profile versions.
130
- * V1: baseline (PBKDF2-HMAC-SHA256, AES-256-GCM, 12-byte nonce, 16-byte tag).
131
- * Append new members sequentially; never change existing values.
88
+ * AES-GCM encryption options: nonce size, tag size, and optional AAD.
89
+ * Mutable builder-style; call {@link build} to validate.
132
90
  */
133
- declare enum CryptoVersion {
134
- /** Version 1 — initial profile. */
135
- V1 = 1
91
+ declare class AesGcmOptions {
92
+ private _nonceSize;
93
+ private _tagSize;
94
+ /** Optional Additional Authenticated Data (not encrypted). */
95
+ associatedData?: Uint8Array;
96
+ /** Nonce size in bytes (must be 12). */
97
+ get nonceSize(): number;
98
+ set nonceSize(v: number);
99
+ /** Tag size in bytes (12–16, default 16). */
100
+ get tagSize(): number;
101
+ set tagSize(v: number);
102
+ /** Validates that {@link tagSize} is in the allowed range. */
103
+ validate(): void;
104
+ /** Default preset: nonce=12, tag=16, no AAD. */
105
+ static get default(): AesGcmOptions;
106
+ /** Fluent setter for {@link tagSize}. */
107
+ withTagSize(s: number): this;
108
+ /**
109
+ * Fluent setter for {@link associatedData}.
110
+ * Accepts a byte array or a UTF-8 string (encoded internally).
111
+ */
112
+ withAssociatedData(aad: Uint8Array | string | undefined): this;
113
+ /** Validates and returns this instance. */
114
+ build(): AesGcmOptions;
115
+ }
116
+
117
+ /**
118
+ * PBKDF2 key derivation options: iterations count and hash algorithm.
119
+ * Mutable builder-style; call {@link build} to validate.
120
+ */
121
+ declare class KdfOptions {
122
+ private _pbkdf2Iterations;
123
+ private _hashAlgorithm;
124
+ /** PBKDF2 iteration count (minimum 100_000). */
125
+ get pbkdf2Iterations(): number;
126
+ set pbkdf2Iterations(v: number);
127
+ /** Hash algorithm used by PBKDF2. Must be one of {@link SupportedHashAlgorithms}. */
128
+ get hashAlgorithm(): HashAlgorithm;
129
+ set hashAlgorithm(v: HashAlgorithm);
130
+ /** Validates iterations and hash algorithm. */
131
+ validate(): void;
132
+ /** Default preset: SHA-256, 600_000 iterations. */
133
+ static get default(): KdfOptions;
134
+ /** Fluent setter for {@link pbkdf2Iterations}. */
135
+ withPbkdf2Iterations(i: number): this;
136
+ /** Fluent setter for {@link hashAlgorithm}. */
137
+ withHashAlgorithm(h: HashAlgorithm): this;
138
+ /** Validates and returns this instance. */
139
+ build(): KdfOptions;
136
140
  }
137
141
 
138
142
  /**
@@ -201,15 +205,15 @@ declare class SrpClientService {
201
205
  * Generates client proof (A, M1, session key S) from server challenge.
202
206
  * @param login - User login.
203
207
  * @param password - Plaintext password.
204
- * @param saltBase64 - Server salt (URL-safe Base64).
205
- * @param B_base64 - Server public ephemeral B (URL-safe Base64).
208
+ * @param saltBase64 - Server salt (standard Base64).
209
+ * @param B_base64 - Server public ephemeral B (standard Base64).
206
210
  * @param ctx - SRP context.
207
- * @returns Object with A, M1, S as Base64 strings.
211
+ * @returns Object with A and M1 as standard Base64; SessionKeyK as raw bytes.
208
212
  */
209
- generateSrpProof(login: string, password: string, saltBase64: string, B_base64: string, ctx: SrpContext): Promise<{
213
+ generateSrpProof(login: string, password: string, saltBase64: string, B_base64: string, ctx: SrpContext, version: CryptoVersion): Promise<{
210
214
  A: string;
211
215
  M1: string;
212
- S: string;
216
+ SessionKeyK: Uint8Array;
213
217
  }>;
214
218
  /**
215
219
  * Validates the server proof M2 to authenticate the server.
@@ -220,7 +224,7 @@ declare class SrpClientService {
220
224
  * @param ctx - SRP context.
221
225
  * @returns True if the server proof is valid.
222
226
  */
223
- verifyServerM2(A_b64: string, M1_b64: string, S_b64: string, serverM2_b64: string, ctx: SrpContext): Promise<boolean>;
227
+ verifyServerM2(A_b64: string, M1_b64: string, sessionKeyK: Uint8Array, serverM2_b64: string, ctx: SrpContext): Promise<boolean>;
224
228
  }
225
229
 
226
230
  /**
@@ -230,11 +234,13 @@ interface SrpSessionState {
230
234
  /** User login identifier. */
231
235
  login: string;
232
236
  /** Server private ephemeral key (Base64). */
233
- privateKeyB: string;
237
+ privateKeyB: Uint8Array;
234
238
  /** Password verifier (Base64). */
235
- verifier: string;
239
+ verifier: Uint8Array;
236
240
  /** Server public ephemeral key B (Base64). */
237
- publicKeyB: string;
241
+ publicKeyB: Uint8Array;
242
+ /** User salt s (needed for RFC 5054 M1). */
243
+ salt: Uint8Array;
238
244
  }
239
245
  /**
240
246
  * Server-side SRP-6a: challenge generation, client proof verification, server proof creation.
@@ -247,7 +253,7 @@ declare class SrpServerService {
247
253
  * @param ctx - SRP context (hash, N, g, etc.).
248
254
  * @returns Session state with private b, verifier, and public B.
249
255
  */
250
- getSrpChallenge(login: string, verifierBytes: Uint8Array, ctx: SrpContext): Promise<SrpSessionState>;
256
+ getSrpChallenge(login: string, verifierBytes: Uint8Array, salt: Uint8Array, ctx: SrpContext): Promise<SrpSessionState>;
251
257
  /**
252
258
  * Verifies client M1 proof and returns server M2 proof.
253
259
  * @param sessionState - Server session state.
@@ -350,12 +356,13 @@ declare class SecurityUtils {
350
356
  static fromBase64(base64: string): Uint8Array;
351
357
  /** Converts big-endian bytes to bigint. */
352
358
  static bytesToBigInt(bytes: Uint8Array): bigint;
353
- /** Converts bigint to fixed-length big-endian bytes (pads/truncates). */
359
+ /** Converts bigint to fixed-length big-endian bytes (pads only; never truncates). */
354
360
  static bigIntToFixedBytes(bn: bigint, length: number): Uint8Array;
355
361
  /** Constant-time comparison of two Uint8Arrays. */
356
362
  static fixedTimeEquals(a: Uint8Array, b: Uint8Array): boolean;
357
363
  /** Modular exponentiation (base^exp mod mod) using binary exponentiation. */
358
364
  static expMod(base: bigint, exp: bigint, mod: bigint): bigint;
365
+ static bigIntToRawBytes(bn: bigint): Uint8Array;
359
366
  }
360
367
 
361
368
  /**
@@ -368,12 +375,30 @@ declare class SrpEncoding {
368
375
  static toHashBytes(ctx: SrpContext, value: bigint): Uint8Array;
369
376
  /** Hashes modulus-sized values (e.g., u = H(A, B)). */
370
377
  static hashModuli(ctx: SrpContext, ...values: bigint[]): Promise<bigint>;
371
- /** Computes M1 = H(A || B || sessionKeyK). */
372
- static computeM1(ctx: SrpContext, A: bigint, B: bigint, sessionKeyK: Uint8Array): Promise<bigint>;
378
+ /**
379
+ * Computes the client proof M1 = H( H(N) ⊕ H(g) | H(I) | s | PAD(A) | PAD(B) | K ).
380
+ *
381
+ * Follows RFC 5054 / SRP-6a:
382
+ * - H(N) and H(g) are hashed as modulus-sized values.
383
+ * - Identity (I) is hashed as raw UTF-8 bytes.
384
+ * - A and B are padded to the modulus size before hashing.
385
+ * - K is the session key (H(S) without padding).
386
+ *
387
+ * @param ctx - SRP context containing N, g, hash algorithm, and modulus size.
388
+ * @param A - Client ephemeral public key.
389
+ * @param B - Server ephemeral public key.
390
+ * @param sessionKeyK - Session key K as raw bytes.
391
+ * @param identity - User identity (login). Must be pre-normalized by the caller.
392
+ * @param salt - User-specific salt bytes.
393
+ * @returns The M1 proof as raw hash bytes.
394
+ */
395
+ static computeM1(ctx: SrpContext, A: bigint, B: bigint, sessionKeyK: Uint8Array, identity: string, salt: Uint8Array): Promise<Uint8Array>;
373
396
  /** Computes M2 = H(A || M1 || sessionKeyK). */
374
- static computeM2(ctx: SrpContext, A: bigint, M1: bigint, sessionKeyK: Uint8Array): Promise<bigint>;
397
+ static computeM2(ctx: SrpContext, A: bigint, m1Bytes: Uint8Array, sessionKeyK: Uint8Array): Promise<Uint8Array>;
375
398
  /** Computes session key K = H(S). */
376
399
  static computeSessionKey(ctx: SrpContext, S: bigint): Promise<Uint8Array>;
400
+ /** Hashes bytes and returns raw Uint8Array (для M1/M2). */
401
+ private static computeHash;
377
402
  /** Concatenates byte arrays and returns the hash as bigint. */
378
403
  private static hash;
379
404
  }