@vex-chat/libvex 9.1.0 → 10.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.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/dist/Client.d.ts +3 -21
  3. package/dist/Client.d.ts.map +1 -1
  4. package/dist/Client.js +42 -118
  5. package/dist/Client.js.map +1 -1
  6. package/dist/__tests__/harness/memory-storage.d.ts.map +1 -1
  7. package/dist/__tests__/harness/memory-storage.js +6 -19
  8. package/dist/__tests__/harness/memory-storage.js.map +1 -1
  9. package/dist/preset/node.d.ts.map +1 -1
  10. package/dist/preset/node.js +1 -2
  11. package/dist/preset/node.js.map +1 -1
  12. package/dist/preset/test.d.ts.map +1 -1
  13. package/dist/preset/test.js +1 -2
  14. package/dist/preset/test.js.map +1 -1
  15. package/dist/storage/sqlite.d.ts.map +1 -1
  16. package/dist/storage/sqlite.js +5 -15
  17. package/dist/storage/sqlite.js.map +1 -1
  18. package/dist/utils/resolveAtRestAesKey.d.ts +1 -3
  19. package/dist/utils/resolveAtRestAesKey.d.ts.map +1 -1
  20. package/dist/utils/resolveAtRestAesKey.js +7 -13
  21. package/dist/utils/resolveAtRestAesKey.js.map +1 -1
  22. package/dist/utils/verifyKeyBundle.d.ts +1 -2
  23. package/dist/utils/verifyKeyBundle.d.ts.map +1 -1
  24. package/dist/utils/verifyKeyBundle.js +7 -10
  25. package/dist/utils/verifyKeyBundle.js.map +1 -1
  26. package/package.json +2 -2
  27. package/src/Client.ts +57 -182
  28. package/src/__tests__/harness/memory-storage.ts +17 -48
  29. package/src/__tests__/harness/shared-suite.ts +7 -137
  30. package/src/__tests__/platform-browser.test.ts +1 -6
  31. package/src/__tests__/platform-node.test.ts +1 -7
  32. package/src/__tests__/prekey-reuse.test.ts +8 -77
  33. package/src/__tests__/verifyKeyBundle.test.ts +15 -43
  34. package/src/preset/node.ts +1 -5
  35. package/src/preset/test.ts +1 -5
  36. package/src/storage/sqlite.ts +4 -20
  37. package/src/utils/resolveAtRestAesKey.ts +7 -23
  38. package/src/utils/verifyKeyBundle.ts +2 -16
  39. package/dist/utils/fipsMailExtra.d.ts +0 -30
  40. package/dist/utils/fipsMailExtra.d.ts.map +0 -1
  41. package/dist/utils/fipsMailExtra.js +0 -114
  42. package/dist/utils/fipsMailExtra.js.map +0 -1
  43. package/src/utils/fipsMailExtra.ts +0 -164
package/src/Client.ts CHANGED
@@ -52,17 +52,11 @@ import type {
52
52
  import type { ClientMessage } from "@vex-chat/types";
53
53
 
54
54
  import {
55
- type CryptoProfile,
56
- enterCryptoProfileScope,
57
- getCryptoProfile,
58
- leaveCryptoProfileScope,
59
- setCryptoProfile,
60
55
  xBoxKeyPairAsync,
61
56
  xBoxKeyPairFromSecretAsync,
62
57
  xConcat,
63
58
  xConstants,
64
59
  xDHAsync,
65
- xEcdhKeyPairFromEcdsaKeyPairAsync,
66
60
  xEncode,
67
61
  xHMAC,
68
62
  xKDF,
@@ -78,7 +72,6 @@ import {
78
72
  xSignKeyPair,
79
73
  xSignKeyPairAsync,
80
74
  xSignKeyPairFromSecret,
81
- xSignKeyPairFromSecretAsync,
82
75
  xSignOpenAsync,
83
76
  XUtils,
84
77
  } from "@vex-chat/crypto";
@@ -113,12 +106,6 @@ import {
113
106
  WebSocketAdapter,
114
107
  WebSocketNotOpenError,
115
108
  } from "./transport/websocket.js";
116
- import {
117
- decodeFipsInitialExtraV1,
118
- encodeFipsInitialExtraV1,
119
- fipsP256AdFromIdentityPubs,
120
- isFipsInitialExtraV1,
121
- } from "./utils/fipsMailExtra.js";
122
109
  import {
123
110
  decodeRatchetHeader,
124
111
  deriveBootstrapSendChain,
@@ -465,12 +452,6 @@ export interface Channels {
465
452
  * ClientOptions are the options you can pass into the client.
466
453
  */
467
454
  export interface ClientOptions {
468
- /**
469
- * Select crypto profile from `@vex-chat/crypto` (`setCryptoProfile`):
470
- * `tweetnacl` (Ed25519 / X25519) or `fips` (P-256 + Web Crypto, separate wire
471
- * layout). Deployments do not interop across profiles; pick one for all peers and server.
472
- */
473
- cryptoProfile?: "fips" | "tweetnacl";
474
455
  /** Folder path where the sqlite file is created. */
475
456
  dbFolder?: string;
476
457
  /**
@@ -1768,8 +1749,6 @@ export class Client {
1768
1749
 
1769
1750
  private autoReconnectEnabled = false;
1770
1751
 
1771
- private readonly cryptoProfile: CryptoProfile;
1772
-
1773
1752
  private readonly database: Storage;
1774
1753
 
1775
1754
  private readonly dbPath: string;
@@ -1840,7 +1819,6 @@ export class Client {
1840
1819
 
1841
1820
  private constructor(
1842
1821
  material: {
1843
- cryptoProfile: CryptoProfile;
1844
1822
  idKeys: KeyPair;
1845
1823
  signKeys: KeyPair;
1846
1824
  },
@@ -1851,7 +1829,6 @@ export class Client {
1851
1829
  this.localMessageRetentionDays = clampLocalMessageRetentionDays(
1852
1830
  options?.localMessageRetentionDays,
1853
1831
  );
1854
- this.cryptoProfile = material.cryptoProfile;
1855
1832
  this.signKeys = material.signKeys;
1856
1833
  this.idKeys = material.idKeys;
1857
1834
 
@@ -1916,47 +1893,15 @@ export class Client {
1916
1893
  options?: ClientOptions,
1917
1894
  storage?: Storage,
1918
1895
  ): Promise<Client> => {
1919
- const profile = options?.cryptoProfile ?? "tweetnacl";
1920
- setCryptoProfile(profile);
1921
-
1922
- if (
1923
- profile === "fips" &&
1924
- typeof globalThis.crypto.subtle !== "object"
1925
- ) {
1926
- throw new Error(
1927
- 'cryptoProfile="fips" requires Web Crypto (globalThis.crypto.subtle).',
1928
- );
1896
+ const signKeys = privateKey
1897
+ ? xSignKeyPairFromSecret(XUtils.decodeHex(privateKey))
1898
+ : xSignKeyPair();
1899
+ const idKeys = XKeyConvert.convertKeyPair(signKeys);
1900
+ if (!idKeys) {
1901
+ throw new Error("Could not convert key to X25519!");
1929
1902
  }
1930
1903
 
1931
- let signKeys: KeyPair;
1932
- if (privateKey) {
1933
- const d = XUtils.decodeHex(privateKey);
1934
- signKeys =
1935
- profile === "tweetnacl"
1936
- ? xSignKeyPairFromSecret(d)
1937
- : await xSignKeyPairFromSecretAsync(d);
1938
- } else {
1939
- signKeys =
1940
- profile === "tweetnacl"
1941
- ? xSignKeyPair()
1942
- : await xSignKeyPairAsync();
1943
- }
1944
-
1945
- const idKeys =
1946
- profile === "tweetnacl"
1947
- ? (() => {
1948
- const c = XKeyConvert.convertKeyPair(signKeys);
1949
- if (!c) {
1950
- throw new Error("Could not convert key to X25519!");
1951
- }
1952
- return c;
1953
- })()
1954
- : await xEcdhKeyPairFromEcdsaKeyPairAsync(signKeys);
1955
-
1956
- const atRestAes = XUtils.deriveLocalAtRestAesKey(
1957
- idKeys.secretKey,
1958
- profile,
1959
- );
1904
+ const atRestAes = XUtils.deriveLocalAtRestAesKey(idKeys.secretKey);
1960
1905
 
1961
1906
  let resolvedStorage = storage;
1962
1907
  if (!resolvedStorage) {
@@ -1992,7 +1937,6 @@ export class Client {
1992
1937
 
1993
1938
  const client = new Client(
1994
1939
  {
1995
- cryptoProfile: profile,
1996
1940
  idKeys,
1997
1941
  signKeys,
1998
1942
  },
@@ -2003,27 +1947,14 @@ export class Client {
2003
1947
  return client;
2004
1948
  };
2005
1949
 
2006
- /**
2007
- * Generates a signing secret key as a hex string (tweetnacl: Ed25519; fips: P-256 pkcs8).
2008
- * In `fips` mode, use `Client.generateSecretKeyAsync()` instead (Web Crypto is async).
2009
- */
1950
+ /** Generates an Ed25519 signing secret key as a hex string. */
2010
1951
  public static generateSecretKey(): string {
2011
- if (getCryptoProfile() === "fips") {
2012
- throw new Error(
2013
- 'Use await Client.generateSecretKeyAsync() when the active crypto profile is "fips".',
2014
- );
2015
- }
2016
1952
  return XUtils.encodeHex(xSignKeyPair().secretKey);
2017
1953
  }
2018
1954
 
2019
- /**
2020
- * Async key generation — required for `fips` profile; safe for `tweetnacl` as well.
2021
- */
1955
+ /** Async Ed25519 key generation. */
2022
1956
  public static async generateSecretKeyAsync(): Promise<string> {
2023
- if (getCryptoProfile() === "fips") {
2024
- return XUtils.encodeHex((await xSignKeyPairAsync()).secretKey);
2025
- }
2026
- return XUtils.encodeHex(xSignKeyPair().secretKey);
1957
+ return XUtils.encodeHex((await xSignKeyPairAsync()).secretKey);
2027
1958
  }
2028
1959
 
2029
1960
  /**
@@ -2054,11 +1985,7 @@ export class Client {
2054
1985
  ): Uint8Array[] {
2055
1986
  switch (type) {
2056
1987
  case MailType.initial: {
2057
- if (isFipsInitialExtraV1(extra)) {
2058
- const [a, b, c, d] = decodeFipsInitialExtraV1(extra);
2059
- return [a, b, c, d];
2060
- }
2061
- /* 32B sign | 32B eph | 32B PK | 68B AD | 6B index (tweetnacl) */
1988
+ /* 32B sign | 32B eph | 32B PK | 68B AD | 6B index */
2062
1989
  const signKey = extra.slice(0, 32);
2063
1990
  const ephKey = extra.slice(32, 64);
2064
1991
  const ad = extra.slice(96, 164);
@@ -2765,12 +2692,9 @@ export class Client {
2765
2692
 
2766
2693
  // returns the file details and the encryption key
2767
2694
  private async createFile(file: Uint8Array): Promise<[FileSQL, string]> {
2768
- return this.runWithThisCryptoProfile(async () => {
2695
+ return this.runCrypto(async () => {
2769
2696
  const nonce = xMakeNonce();
2770
- const fileKey: Uint8Array =
2771
- this.cryptoProfile === "fips"
2772
- ? xRandomBytes(32)
2773
- : (await xBoxKeyPairAsync()).secretKey;
2697
+ const fileKey = (await xBoxKeyPairAsync()).secretKey;
2774
2698
  const box = await xSecretboxAsync(
2775
2699
  Uint8Array.from(file),
2776
2700
  nonce,
@@ -2864,13 +2788,9 @@ export class Client {
2864
2788
  private async createPreKey(
2865
2789
  kind: "one-time" | "signed",
2866
2790
  ): Promise<UnsavedPreKey> {
2867
- return this.runWithThisCryptoProfile(async () => {
2791
+ return this.runCrypto(async () => {
2868
2792
  const preKeyPair = await xBoxKeyPairAsync();
2869
- const toSign = xPreKeySignaturePayload(
2870
- preKeyPair.publicKey,
2871
- kind,
2872
- this.cryptoProfile,
2873
- );
2793
+ const toSign = xPreKeySignaturePayload(preKeyPair.publicKey, kind);
2874
2794
  return {
2875
2795
  keyPair: preKeyPair,
2876
2796
  signature: await xSignAsync(toSign, this.signKeys.secretKey),
@@ -2902,16 +2822,12 @@ export class Client {
2902
2822
  */
2903
2823
  allowKeyBundleFailure = false,
2904
2824
  ): Promise<Message | null> {
2905
- return this.runWithThisCryptoProfile(async () => {
2825
+ return this.runCrypto(async () => {
2906
2826
  let keyBundle: KeyBundle;
2907
2827
 
2908
2828
  try {
2909
2829
  keyBundle = await this.retrieveKeyBundle(device.deviceID);
2910
- await verifyKeyBundleSignatures(
2911
- keyBundle,
2912
- device,
2913
- this.cryptoProfile,
2914
- );
2830
+ await verifyKeyBundleSignatures(keyBundle, device);
2915
2831
  } catch (e) {
2916
2832
  if (allowKeyBundleFailure) {
2917
2833
  return null;
@@ -2937,25 +2853,16 @@ export class Client {
2937
2853
  const ephemeralKeys = await xBoxKeyPairAsync();
2938
2854
  const EK_A = ephemeralKeys.secretKey;
2939
2855
 
2940
- const fips = this.cryptoProfile === "fips";
2941
- // their keys — FIPS: `signKey` in bundle is the peer P-256 ECDH identity (raw, typically 65B).
2942
2856
  const SPK_B = new Uint8Array(keyBundle.preKey.publicKey);
2943
2857
  const OPK_B = keyBundle.otk
2944
2858
  ? new Uint8Array(keyBundle.otk.publicKey)
2945
2859
  : null;
2946
- const IK_B = fips
2947
- ? new Uint8Array(keyBundle.signKey)
2948
- : (() => {
2949
- const c = XKeyConvert.convertPublicKey(
2950
- new Uint8Array(keyBundle.signKey),
2951
- );
2952
- if (!c) {
2953
- throw new Error(
2954
- "Could not convert sign key to X25519.",
2955
- );
2956
- }
2957
- return c;
2958
- })();
2860
+ const IK_B = XKeyConvert.convertPublicKey(
2861
+ new Uint8Array(keyBundle.signKey),
2862
+ );
2863
+ if (!IK_B) {
2864
+ throw new Error("Could not convert sign key to X25519.");
2865
+ }
2959
2866
 
2960
2867
  // diffie hellman functions
2961
2868
  const DH1 = await xDHAsync(new Uint8Array(IK_A), SPK_B);
@@ -2980,15 +2887,10 @@ export class Client {
2980
2887
  const initialSubkeys = xMessageKeySubkeys(SK);
2981
2888
  const PK = (await xBoxKeyPairFromSecretAsync(SK)).publicKey;
2982
2889
 
2983
- const AD = fips
2984
- ? fipsP256AdFromIdentityPubs(
2985
- IK_AP,
2986
- new Uint8Array(keyBundle.signKey),
2987
- )
2988
- : xConcat(
2989
- xEncode(xConstants.CURVE, IK_AP),
2990
- xEncode(xConstants.CURVE, IK_B),
2991
- );
2890
+ const AD = xConcat(
2891
+ xEncode(xConstants.CURVE, IK_AP),
2892
+ xEncode(xConstants.CURVE, IK_B),
2893
+ );
2992
2894
 
2993
2895
  const nonce = xMakeNonce();
2994
2896
  const cipher = await xSecretboxAsync(
@@ -2997,18 +2899,13 @@ export class Client {
2997
2899
  initialSubkeys.encryptionKey,
2998
2900
  );
2999
2901
 
3000
- const signKeyWire = fips ? IK_AP : this.signKeys.publicKey;
3001
- const ephKeyWire = ephemeralKeys.publicKey;
3002
-
3003
- const extra = fips
3004
- ? encodeFipsInitialExtraV1(signKeyWire, ephKeyWire, PK, AD, IDX)
3005
- : xConcat(
3006
- this.signKeys.publicKey,
3007
- ephemeralKeys.publicKey,
3008
- PK,
3009
- AD,
3010
- IDX,
3011
- );
2902
+ const extra = xConcat(
2903
+ this.signKeys.publicKey,
2904
+ ephemeralKeys.publicKey,
2905
+ PK,
2906
+ AD,
2907
+ IDX,
2908
+ );
3012
2909
 
3013
2910
  const mail: MailWS = {
3014
2911
  authorID: this.getUser().userID,
@@ -3806,7 +3703,16 @@ export class Client {
3806
3703
  }
3807
3704
 
3808
3705
  private getServerIconURL(iconID: string): string {
3809
- return this.getHost() + "/server-icon/" + encodeURIComponent(iconID);
3706
+ const normalizedIconID = iconID.trim();
3707
+ if (!normalizedIconID) {
3708
+ throw new Error("Server icon ID cannot be empty.");
3709
+ }
3710
+
3711
+ return (
3712
+ this.getHost() +
3713
+ "/server-icon/" +
3714
+ encodeURIComponent(normalizedIconID)
3715
+ );
3810
3716
  }
3811
3717
 
3812
3718
  private async getServerList(): Promise<Server[]> {
@@ -4091,11 +3997,10 @@ export class Client {
4091
3997
  private async isPreKeySignedByCurrentDevice(
4092
3998
  preKey: PreKeysCrypto,
4093
3999
  ): Promise<boolean> {
4094
- return this.runWithThisCryptoProfile(async () => {
4000
+ return this.runCrypto(async () => {
4095
4001
  const payload = xPreKeySignaturePayload(
4096
4002
  preKey.keyPair.publicKey,
4097
4003
  "signed",
4098
- this.cryptoProfile,
4099
4004
  );
4100
4005
  const opened = await xSignOpenAsync(
4101
4006
  preKey.signature,
@@ -4312,7 +4217,7 @@ export class Client {
4312
4217
  }
4313
4218
 
4314
4219
  private async populateKeyRing() {
4315
- await this.runWithThisCryptoProfile(async () => {
4220
+ await this.runCrypto(async () => {
4316
4221
  // we've checked in the constructor that these exist
4317
4222
  if (!this.idKeys) {
4318
4223
  throw new Error("Identity keys are missing.");
@@ -4491,7 +4396,7 @@ export class Client {
4491
4396
  this.reading = true;
4492
4397
 
4493
4398
  try {
4494
- await this.runWithThisCryptoProfile(async () => {
4399
+ await this.runCrypto(async () => {
4495
4400
  const healSession = () => {
4496
4401
  if (this.manuallyClosing || !this.xKeyRing) {
4497
4402
  return;
@@ -4604,19 +4509,7 @@ export class Client {
4604
4509
  }
4605
4510
 
4606
4511
  // their public keys
4607
- const fipsRead = isFipsInitialExtraV1(
4608
- new Uint8Array(mail.extra),
4609
- );
4610
- const IK_A = fipsRead
4611
- ? signKey
4612
- : (() => {
4613
- const c =
4614
- XKeyConvert.convertPublicKey(signKey);
4615
- if (!c) {
4616
- return null;
4617
- }
4618
- return c;
4619
- })();
4512
+ const IK_A = XKeyConvert.convertPublicKey(signKey);
4620
4513
  if (!IK_A) {
4621
4514
  const failureCount =
4622
4515
  this.registerDecryptFailure(mail);
@@ -4626,7 +4519,6 @@ export class Client {
4626
4519
  "readMail initial: abort (IK_A null, Ed→X25519?)",
4627
4520
  {
4628
4521
  attempts: failureCount,
4629
- fips: String(fipsRead),
4630
4522
  mailID: mail.mailID,
4631
4523
  thisDevice:
4632
4524
  this.getDevice().deviceID,
@@ -4696,12 +4588,10 @@ export class Client {
4696
4588
  );
4697
4589
 
4698
4590
  // associated data
4699
- const AD = fipsRead
4700
- ? fipsP256AdFromIdentityPubs(IK_A, IK_BP)
4701
- : xConcat(
4702
- xEncode(xConstants.CURVE, IK_A),
4703
- xEncode(xConstants.CURVE, IK_BP),
4704
- );
4591
+ const AD = xConcat(
4592
+ xEncode(xConstants.CURVE, IK_A),
4593
+ xEncode(xConstants.CURVE, IK_BP),
4594
+ );
4705
4595
 
4706
4596
  if (!XUtils.bytesEqual(hmac, header)) {
4707
4597
  const failureCount =
@@ -5302,9 +5192,7 @@ export class Client {
5302
5192
  throw new Error("Couldn't fetch token.");
5303
5193
  }
5304
5194
 
5305
- // Stored on Spire for signature verification: Ed25519 (hex) in tweetnacl;
5306
- // P-256 ECDSA SPKI (hex) in FIPS. The server maps this to a raw ECDH
5307
- // identity in `getKeyBundle` for X3DH; see spire `Database.getKeyBundle`.
5195
+ // Stored on Spire for Ed25519 signature verification.
5308
5196
  const signKey = this.getKeys().public;
5309
5197
  const signed = XUtils.encodeHex(
5310
5198
  await xSignAsync(
@@ -5499,6 +5387,10 @@ export class Client {
5499
5387
  return device;
5500
5388
  }
5501
5389
 
5390
+ private async runCrypto<T>(fn: () => Promise<T>): Promise<T> {
5391
+ return fn();
5392
+ }
5393
+
5502
5394
  private async runLocalRetentionPurge(): Promise<void> {
5503
5395
  if (this.isManualCloseInFlight()) {
5504
5396
  return;
@@ -5512,23 +5404,6 @@ export class Client {
5512
5404
  }
5513
5405
  }
5514
5406
 
5515
- /**
5516
- * `xDHAsync` and other helpers in `@vex-chat/crypto` use the process-wide
5517
- * active profile. When several {@link Client} instances use different
5518
- * `cryptoProfile` values, scope the global to this instance for the duration
5519
- * of that crypto work.
5520
- */
5521
- private async runWithThisCryptoProfile<T>(
5522
- fn: () => Promise<T>,
5523
- ): Promise<T> {
5524
- enterCryptoProfileScope(this.cryptoProfile);
5525
- try {
5526
- return await fn();
5527
- } finally {
5528
- leaveCryptoProfileScope();
5529
- }
5530
- }
5531
-
5532
5407
  private scheduleMailBatchFlush(): void {
5533
5408
  if (this.mailBatchFlushTimer) {
5534
5409
  return;
@@ -14,12 +14,8 @@ import type {
14
14
  import type { Device, PreKeysSQL, SessionSQL } from "@vex-chat/types";
15
15
 
16
16
  import {
17
- getCryptoProfile,
18
17
  xBoxKeyPairFromSecret,
19
- xBoxKeyPairFromSecretAsync,
20
- xSecretbox,
21
18
  xSecretboxAsync,
22
- xSecretboxOpen,
23
19
  xSecretboxOpenAsync,
24
20
  XUtils,
25
21
  } from "@vex-chat/crypto";
@@ -117,10 +113,7 @@ export class MemoryStorage extends EventEmitter implements Storage {
117
113
  const sk = XUtils.decodeHex(otk.privateKey);
118
114
  return {
119
115
  index: otk.index,
120
- keyPair:
121
- getCryptoProfile() === "fips"
122
- ? await xBoxKeyPairFromSecretAsync(sk)
123
- : xBoxKeyPairFromSecret(sk),
116
+ keyPair: xBoxKeyPairFromSecret(sk),
124
117
  signature: XUtils.decodeHex(otk.signature),
125
118
  };
126
119
  }
@@ -132,10 +125,7 @@ export class MemoryStorage extends EventEmitter implements Storage {
132
125
  const sk = XUtils.decodeHex(pk.privateKey);
133
126
  return {
134
127
  index: pk.index,
135
- keyPair:
136
- getCryptoProfile() === "fips"
137
- ? await xBoxKeyPairFromSecretAsync(sk)
138
- : xBoxKeyPairFromSecret(sk),
128
+ keyPair: xBoxKeyPairFromSecret(sk),
139
129
  signature: XUtils.decodeHex(pk.signature),
140
130
  };
141
131
  }
@@ -223,18 +213,11 @@ export class MemoryStorage extends EventEmitter implements Storage {
223
213
  return;
224
214
  }
225
215
  const copy = { ...message };
226
- const fips = getCryptoProfile() === "fips";
227
- const ct = fips
228
- ? await xSecretboxAsync(
229
- XUtils.decodeUTF8(message.message),
230
- XUtils.decodeHex(message.nonce),
231
- this.atRestAesKey,
232
- )
233
- : xSecretbox(
234
- XUtils.decodeUTF8(message.message),
235
- XUtils.decodeHex(message.nonce),
236
- this.atRestAesKey,
237
- );
216
+ const ct = await xSecretboxAsync(
217
+ XUtils.decodeUTF8(message.message),
218
+ XUtils.decodeHex(message.nonce),
219
+ this.atRestAesKey,
220
+ );
238
221
  copy.message = XUtils.encodeHex(ct);
239
222
  this.messages.push(copy);
240
223
  }
@@ -302,18 +285,11 @@ export class MemoryStorage extends EventEmitter implements Storage {
302
285
  next.extra = patch.extra;
303
286
  }
304
287
  if (patch.message !== undefined) {
305
- const fips = getCryptoProfile() === "fips";
306
- const ct = fips
307
- ? await xSecretboxAsync(
308
- XUtils.decodeUTF8(patch.message),
309
- XUtils.decodeHex(current.nonce),
310
- this.atRestAesKey,
311
- )
312
- : xSecretbox(
313
- XUtils.decodeUTF8(patch.message),
314
- XUtils.decodeHex(current.nonce),
315
- this.atRestAesKey,
316
- );
288
+ const ct = await xSecretboxAsync(
289
+ XUtils.decodeUTF8(patch.message),
290
+ XUtils.decodeHex(current.nonce),
291
+ this.atRestAesKey,
292
+ );
317
293
  next.message = XUtils.encodeHex(ct);
318
294
  }
319
295
  this.messages[idx] = next;
@@ -323,18 +299,11 @@ export class MemoryStorage extends EventEmitter implements Storage {
323
299
  private async decryptMessage(msg: Message): Promise<Message> {
324
300
  const copy = { ...msg };
325
301
  if (copy.decrypted) {
326
- const fips = getCryptoProfile() === "fips";
327
- const dec = fips
328
- ? await xSecretboxOpenAsync(
329
- XUtils.decodeHex(copy.message),
330
- XUtils.decodeHex(copy.nonce),
331
- this.atRestAesKey,
332
- )
333
- : xSecretboxOpen(
334
- XUtils.decodeHex(copy.message),
335
- XUtils.decodeHex(copy.nonce),
336
- this.atRestAesKey,
337
- );
302
+ const dec = await xSecretboxOpenAsync(
303
+ XUtils.decodeHex(copy.message),
304
+ XUtils.decodeHex(copy.nonce),
305
+ this.atRestAesKey,
306
+ );
338
307
  if (dec) copy.message = XUtils.encodeUTF8(dec);
339
308
  }
340
309
  return copy;