@towns-protocol/sdk-crypto 0.0.244

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/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 River Association
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @towns-protocol/sdk-crypto
2
+
3
+ This package provides a set of cryptographic functions used in the Towns Protocol SDK.
4
+
5
+ It's required to be a package so we can properly bundle the code for the web and node.
@@ -0,0 +1,30 @@
1
+ //#region rolldown:runtime
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 __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+
25
+ Object.defineProperty(exports, '__toESM', {
26
+ enumerable: true,
27
+ get: function () {
28
+ return __toESM;
29
+ }
30
+ });
@@ -0,0 +1,90 @@
1
+ const require_chunk = require('../chunk-CUT6urMc.cjs');
2
+ const __towns_protocol_dlog = require_chunk.__toESM(require("@towns-protocol/dlog"));
3
+ const __towns_protocol_proto = require_chunk.__toESM(require("@towns-protocol/proto"));
4
+ const __towns_protocol_encryption = require_chunk.__toESM(require("@towns-protocol/encryption"));
5
+ const node_crypto = require_chunk.__toESM(require("node:crypto"));
6
+
7
+ //#region src/node/index.ts
8
+ function uint8ArrayToBase64(uint8Array) {
9
+ return Buffer.from(uint8Array).toString("base64");
10
+ }
11
+ function base64ToUint8Array(base64) {
12
+ const buffer = Buffer.from(base64, "base64");
13
+ return new Uint8Array(buffer);
14
+ }
15
+ function bufferToUint8Array(buffer) {
16
+ return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
17
+ }
18
+ function uint8ArrayToBuffer(uint8Array) {
19
+ return Buffer.from(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength);
20
+ }
21
+ async function getExtendedKeyMaterial(seedBuffer, length) {
22
+ const hash = node_crypto.default.createHash("sha256");
23
+ hash.update(uint8ArrayToBuffer(seedBuffer));
24
+ let keyMaterial = bufferToUint8Array(hash.digest());
25
+ while (keyMaterial.length < length) {
26
+ const newHash = node_crypto.default.createHash("sha256");
27
+ newHash.update(uint8ArrayToBuffer(keyMaterial));
28
+ keyMaterial = new Uint8Array([...keyMaterial, ...bufferToUint8Array(newHash.digest())]);
29
+ }
30
+ return keyMaterial.slice(0, length);
31
+ }
32
+ async function deriveKeyAndIV(keyPhrase) {
33
+ let keyBuffer;
34
+ if (typeof keyPhrase === "string") {
35
+ const encoder = new TextEncoder();
36
+ keyBuffer = encoder.encode(keyPhrase);
37
+ } else keyBuffer = keyPhrase;
38
+ const keyMaterial = await getExtendedKeyMaterial(keyBuffer, 44);
39
+ const key = keyMaterial.slice(0, 32);
40
+ const iv = keyMaterial.slice(32, 44);
41
+ return {
42
+ key,
43
+ iv
44
+ };
45
+ }
46
+ async function encryptAESGCM(data, key, iv) {
47
+ if (!data || data.length === 0) throw new Error("Cannot encrypt undefined or empty data");
48
+ if (!key) key = node_crypto.default.randomBytes(32);
49
+ else if (key.length !== 32) throw new Error("Invalid key length. AES-256-GCM requires a 32-byte key.");
50
+ if (!iv) iv = node_crypto.default.randomBytes(12);
51
+ else if (iv.length !== 12) throw new Error("Invalid IV length. AES-256-GCM requires a 12-byte IV.");
52
+ const cipher = node_crypto.default.createCipheriv("aes-256-gcm", uint8ArrayToBuffer(key), uint8ArrayToBuffer(iv));
53
+ const encrypted = Buffer.concat([cipher.update(uint8ArrayToBuffer(data)), cipher.final()]);
54
+ const authTag = cipher.getAuthTag();
55
+ const ciphertext = Buffer.concat([encrypted, authTag]);
56
+ return {
57
+ ciphertext: bufferToUint8Array(ciphertext),
58
+ iv,
59
+ secretKey: key
60
+ };
61
+ }
62
+ async function decryptAESGCM(data, key, iv) {
63
+ if (key.length !== 32) throw new Error("Invalid key length. AES-256-GCM requires a 32-byte key.");
64
+ if (iv.length !== 12) throw new Error("Invalid IV length. AES-256-GCM requires a 12-byte IV.");
65
+ let dataBuffer;
66
+ if (typeof data === "string") dataBuffer = Buffer.from(data, "base64");
67
+ else dataBuffer = data;
68
+ const encryptedBuffer = Buffer.from(dataBuffer.buffer, dataBuffer.byteOffset, dataBuffer.byteLength);
69
+ const authTag = new Uint8Array(encryptedBuffer.buffer.slice(encryptedBuffer.byteOffset + encryptedBuffer.length - 16, encryptedBuffer.byteOffset + encryptedBuffer.length));
70
+ const encryptedContent = new Uint8Array(encryptedBuffer.buffer.slice(encryptedBuffer.byteOffset, encryptedBuffer.byteOffset + encryptedBuffer.length - 16));
71
+ const decipher = node_crypto.default.createDecipheriv("aes-256-gcm", key, iv);
72
+ decipher.setAuthTag(authTag);
73
+ const decrypted = Buffer.concat([decipher.update(encryptedContent), decipher.final()]);
74
+ return new Uint8Array(decrypted.buffer, decrypted.byteOffset, decrypted.byteLength);
75
+ }
76
+ async function decryptDerivedAESGCM(keyPhrase, encryptedData) {
77
+ if (encryptedData.algorithm !== __towns_protocol_encryption.AES_GCM_DERIVED_ALGORITHM) (0, __towns_protocol_dlog.throwWithCode)(`${encryptedData.algorithm}" algorithm not implemented`, __towns_protocol_proto.Err.UNIMPLEMENTED);
78
+ const { key, iv } = await deriveKeyAndIV(keyPhrase);
79
+ const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
80
+ return decryptAESGCM(ciphertext, key, iv);
81
+ }
82
+
83
+ //#endregion
84
+ exports.base64ToUint8Array = base64ToUint8Array;
85
+ exports.decryptAESGCM = decryptAESGCM;
86
+ exports.decryptDerivedAESGCM = decryptDerivedAESGCM;
87
+ exports.deriveKeyAndIV = deriveKeyAndIV;
88
+ exports.encryptAESGCM = encryptAESGCM;
89
+ exports.uint8ArrayToBase64 = uint8ArrayToBase64;
90
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["uint8Array: Uint8Array","base64: string","buffer: Buffer","seedBuffer: Uint8Array","length: number","keyPhrase: string | Uint8Array","keyBuffer: Uint8Array","data: Uint8Array","key?: Uint8Array","iv?: Uint8Array","data: Uint8Array | string","key: Uint8Array","iv: Uint8Array","dataBuffer: Uint8Array","keyPhrase: string","encryptedData: EncryptedData","AES_GCM_DERIVED_ALGORITHM","Err"],"sources":["../../src/node/index.ts"],"sourcesContent":["import { throwWithCode } from '@towns-protocol/dlog'\nimport { EncryptedData, Err } from '@towns-protocol/proto'\nimport { AES_GCM_DERIVED_ALGORITHM } from '@towns-protocol/encryption'\nimport crypto from 'node:crypto'\n\nexport function uint8ArrayToBase64(uint8Array: Uint8Array): string {\n return Buffer.from(uint8Array).toString('base64')\n}\n\nexport function base64ToUint8Array(base64: string): Uint8Array {\n const buffer = Buffer.from(base64, 'base64')\n return new Uint8Array(buffer)\n}\n\nfunction bufferToUint8Array(buffer: Buffer): Uint8Array {\n return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)\n}\n\nfunction uint8ArrayToBuffer(uint8Array: Uint8Array): Buffer {\n return Buffer.from(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength)\n}\n\nasync function getExtendedKeyMaterial(seedBuffer: Uint8Array, length: number): Promise<Uint8Array> {\n const hash = crypto.createHash('sha256')\n hash.update(uint8ArrayToBuffer(seedBuffer))\n let keyMaterial = bufferToUint8Array(hash.digest())\n\n while (keyMaterial.length < length) {\n const newHash = crypto.createHash('sha256')\n newHash.update(uint8ArrayToBuffer(keyMaterial))\n keyMaterial = new Uint8Array([...keyMaterial, ...bufferToUint8Array(newHash.digest())])\n }\n\n return keyMaterial.slice(0, length)\n}\n\nexport async function deriveKeyAndIV(\n keyPhrase: string | Uint8Array,\n): Promise<{ key: Uint8Array; iv: Uint8Array }> {\n let keyBuffer: Uint8Array\n\n if (typeof keyPhrase === 'string') {\n const encoder = new TextEncoder()\n keyBuffer = encoder.encode(keyPhrase)\n } else {\n keyBuffer = keyPhrase\n }\n\n const keyMaterial = await getExtendedKeyMaterial(keyBuffer, 32 + 12) // 32 bytes for key, 12 bytes for IV\n\n const key = keyMaterial.slice(0, 32) // AES-256 key\n const iv = keyMaterial.slice(32, 32 + 12) // AES-GCM IV\n\n return { key, iv }\n}\n\nexport async function encryptAESGCM(\n data: Uint8Array,\n key?: Uint8Array,\n iv?: Uint8Array,\n): Promise<{ ciphertext: Uint8Array; iv: Uint8Array; secretKey: Uint8Array }> {\n if (!data || data.length === 0) {\n throw new Error('Cannot encrypt undefined or empty data')\n }\n\n if (!key) {\n key = crypto.randomBytes(32)\n } else if (key.length !== 32) {\n throw new Error('Invalid key length. AES-256-GCM requires a 32-byte key.')\n }\n\n if (!iv) {\n iv = crypto.randomBytes(12)\n } else if (iv.length !== 12) {\n throw new Error('Invalid IV length. AES-256-GCM requires a 12-byte IV.')\n }\n\n const cipher = crypto.createCipheriv(\n 'aes-256-gcm',\n uint8ArrayToBuffer(key),\n uint8ArrayToBuffer(iv),\n )\n const encrypted = Buffer.concat([cipher.update(uint8ArrayToBuffer(data)), cipher.final()])\n const authTag = cipher.getAuthTag()\n const ciphertext = Buffer.concat([encrypted, authTag])\n\n return { ciphertext: bufferToUint8Array(ciphertext), iv, secretKey: key }\n}\n\nexport async function decryptAESGCM(\n data: Uint8Array | string,\n key: Uint8Array,\n iv: Uint8Array,\n): Promise<Uint8Array> {\n if (key.length !== 32) {\n throw new Error('Invalid key length. AES-256-GCM requires a 32-byte key.')\n }\n\n if (iv.length !== 12) {\n throw new Error('Invalid IV length. AES-256-GCM requires a 12-byte IV.')\n }\n\n // Convert data to Uint8Array if it is a string\n let dataBuffer: Uint8Array\n if (typeof data === 'string') {\n dataBuffer = Buffer.from(data, 'base64')\n } else {\n dataBuffer = data\n }\n\n const encryptedBuffer = Buffer.from(\n dataBuffer.buffer,\n dataBuffer.byteOffset,\n dataBuffer.byteLength,\n )\n const authTag = new Uint8Array(\n encryptedBuffer.buffer.slice(\n encryptedBuffer.byteOffset + encryptedBuffer.length - 16,\n encryptedBuffer.byteOffset + encryptedBuffer.length,\n ),\n )\n const encryptedContent = new Uint8Array(\n encryptedBuffer.buffer.slice(\n encryptedBuffer.byteOffset,\n encryptedBuffer.byteOffset + encryptedBuffer.length - 16,\n ),\n )\n\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv)\n decipher.setAuthTag(authTag)\n\n const decrypted = Buffer.concat([decipher.update(encryptedContent), decipher.final()])\n return new Uint8Array(decrypted.buffer, decrypted.byteOffset, decrypted.byteLength)\n}\n\nexport async function decryptDerivedAESGCM(\n keyPhrase: string,\n encryptedData: EncryptedData,\n): Promise<Uint8Array> {\n if (encryptedData.algorithm !== AES_GCM_DERIVED_ALGORITHM) {\n throwWithCode(`${encryptedData.algorithm}\" algorithm not implemented`, Err.UNIMPLEMENTED)\n }\n const { key, iv } = await deriveKeyAndIV(keyPhrase)\n const ciphertext = base64ToUint8Array(encryptedData.ciphertext)\n return decryptAESGCM(ciphertext, key, iv)\n}\n"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { EncryptedData } from "@towns-protocol/proto";
2
+
3
+ //#region src/node/index.d.ts
4
+ declare function uint8ArrayToBase64(uint8Array: Uint8Array): string;
5
+ declare function base64ToUint8Array(base64: string): Uint8Array;
6
+ declare function deriveKeyAndIV(keyPhrase: string | Uint8Array): Promise<{
7
+ key: Uint8Array;
8
+ iv: Uint8Array;
9
+ }>;
10
+ declare function encryptAESGCM(data: Uint8Array, key?: Uint8Array, iv?: Uint8Array): Promise<{
11
+ ciphertext: Uint8Array;
12
+ iv: Uint8Array;
13
+ secretKey: Uint8Array;
14
+ }>;
15
+ declare function decryptAESGCM(data: Uint8Array | string, key: Uint8Array, iv: Uint8Array): Promise<Uint8Array>;
16
+ declare function decryptDerivedAESGCM(keyPhrase: string, encryptedData: EncryptedData): Promise<Uint8Array>;
17
+ //# sourceMappingURL=index.d.ts.map
18
+
19
+ //#endregion
20
+ export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
21
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/node/index.ts"],"sourcesContent":[],"mappings":";;;iBAKgB,kBAAA,aAA+B;iBAI/B,kBAAA,kBAAoC;AAJpC,iBA+BM,cAAA,CA/ByB,SAAU,EAAA,MAAA,GAgCjC,UAhCiC,CAAA,EAiCtD,OAjCsD,CAAA;EAIzC,GAAA,EA6BE,UA7BF;EA2BM,EAAA,EAEY,UAFZ;CAAc,CAAA;AACZ,iBAmBF,aAAA,CAnBE,IAAA,EAoBd,UApBc,EAAA,GAAA,CAAA,EAqBd,UArBc,EAAA,EAAA,CAAA,EAsBf,UAtBe,CAAA,EAuBrB,OAvBqB,CAAA;EAAU,UAChB,EAsBO,UAtBP;EAAU,EAAA,EAsBa,UAtBP;EAAU,SAAzC,EAsB6D,UAtB7D;AAAO,CAAA,CAAA;AAkBY,iBAiCA,aAAA,CAjCa,IAAA,EAkCzB,UAlCyB,GAAA,MAAA,EAAA,GAAA,EAmC1B,UAnC0B,EAAA,EAAA,EAoC3B,UApC2B,CAAA,EAqChC,OArCgC,CAqCxB,UArCwB,CAAA;AAAA,iBA+Eb,oBAAA,CA/Ea,SAAA,EAAA,MAAA,EAAA,aAAA,EAiFhB,aAjFgB,CAAA,EAkFhC,OAlFgC,CAkFxB,UAlFwB,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { EncryptedData } from "@towns-protocol/proto";
2
+
3
+ //#region src/node/index.d.ts
4
+ declare function uint8ArrayToBase64(uint8Array: Uint8Array): string;
5
+ declare function base64ToUint8Array(base64: string): Uint8Array;
6
+ declare function deriveKeyAndIV(keyPhrase: string | Uint8Array): Promise<{
7
+ key: Uint8Array;
8
+ iv: Uint8Array;
9
+ }>;
10
+ declare function encryptAESGCM(data: Uint8Array, key?: Uint8Array, iv?: Uint8Array): Promise<{
11
+ ciphertext: Uint8Array;
12
+ iv: Uint8Array;
13
+ secretKey: Uint8Array;
14
+ }>;
15
+ declare function decryptAESGCM(data: Uint8Array | string, key: Uint8Array, iv: Uint8Array): Promise<Uint8Array>;
16
+ declare function decryptDerivedAESGCM(keyPhrase: string, encryptedData: EncryptedData): Promise<Uint8Array>;
17
+ //# sourceMappingURL=index.d.ts.map
18
+
19
+ //#endregion
20
+ export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/node/index.ts"],"sourcesContent":[],"mappings":";;;iBAKgB,kBAAA,aAA+B;iBAI/B,kBAAA,kBAAoC;AAJpC,iBA+BM,cAAA,CA/ByB,SAAU,EAAA,MAAA,GAgCjC,UAhCiC,CAAA,EAiCtD,OAjCsD,CAAA;EAIzC,GAAA,EA6BE,UA7BF;EA2BM,EAAA,EAEY,UAFZ;CAAc,CAAA;AACZ,iBAmBF,aAAA,CAnBE,IAAA,EAoBd,UApBc,EAAA,GAAA,CAAA,EAqBd,UArBc,EAAA,EAAA,CAAA,EAsBf,UAtBe,CAAA,EAuBrB,OAvBqB,CAAA;EAAU,UAChB,EAsBO,UAtBP;EAAU,EAAA,EAsBa,UAtBP;EAAU,SAAzC,EAsB6D,UAtB7D;AAAO,CAAA,CAAA;AAkBY,iBAiCA,aAAA,CAjCa,IAAA,EAkCzB,UAlCyB,GAAA,MAAA,EAAA,GAAA,EAmC1B,UAnC0B,EAAA,EAAA,EAoC3B,UApC2B,CAAA,EAqChC,OArCgC,CAqCxB,UArCwB,CAAA;AAAA,iBA+Eb,oBAAA,CA/Ea,SAAA,EAAA,MAAA,EAAA,aAAA,EAiFhB,aAjFgB,CAAA,EAkFhC,OAlFgC,CAkFxB,UAlFwB,CAAA"}
@@ -0,0 +1,84 @@
1
+ import { throwWithCode } from "@towns-protocol/dlog";
2
+ import { Err } from "@towns-protocol/proto";
3
+ import { AES_GCM_DERIVED_ALGORITHM } from "@towns-protocol/encryption";
4
+ import crypto from "node:crypto";
5
+
6
+ //#region src/node/index.ts
7
+ function uint8ArrayToBase64(uint8Array) {
8
+ return Buffer.from(uint8Array).toString("base64");
9
+ }
10
+ function base64ToUint8Array(base64) {
11
+ const buffer = Buffer.from(base64, "base64");
12
+ return new Uint8Array(buffer);
13
+ }
14
+ function bufferToUint8Array(buffer) {
15
+ return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
16
+ }
17
+ function uint8ArrayToBuffer(uint8Array) {
18
+ return Buffer.from(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength);
19
+ }
20
+ async function getExtendedKeyMaterial(seedBuffer, length) {
21
+ const hash = crypto.createHash("sha256");
22
+ hash.update(uint8ArrayToBuffer(seedBuffer));
23
+ let keyMaterial = bufferToUint8Array(hash.digest());
24
+ while (keyMaterial.length < length) {
25
+ const newHash = crypto.createHash("sha256");
26
+ newHash.update(uint8ArrayToBuffer(keyMaterial));
27
+ keyMaterial = new Uint8Array([...keyMaterial, ...bufferToUint8Array(newHash.digest())]);
28
+ }
29
+ return keyMaterial.slice(0, length);
30
+ }
31
+ async function deriveKeyAndIV(keyPhrase) {
32
+ let keyBuffer;
33
+ if (typeof keyPhrase === "string") {
34
+ const encoder = new TextEncoder();
35
+ keyBuffer = encoder.encode(keyPhrase);
36
+ } else keyBuffer = keyPhrase;
37
+ const keyMaterial = await getExtendedKeyMaterial(keyBuffer, 44);
38
+ const key = keyMaterial.slice(0, 32);
39
+ const iv = keyMaterial.slice(32, 44);
40
+ return {
41
+ key,
42
+ iv
43
+ };
44
+ }
45
+ async function encryptAESGCM(data, key, iv) {
46
+ if (!data || data.length === 0) throw new Error("Cannot encrypt undefined or empty data");
47
+ if (!key) key = crypto.randomBytes(32);
48
+ else if (key.length !== 32) throw new Error("Invalid key length. AES-256-GCM requires a 32-byte key.");
49
+ if (!iv) iv = crypto.randomBytes(12);
50
+ else if (iv.length !== 12) throw new Error("Invalid IV length. AES-256-GCM requires a 12-byte IV.");
51
+ const cipher = crypto.createCipheriv("aes-256-gcm", uint8ArrayToBuffer(key), uint8ArrayToBuffer(iv));
52
+ const encrypted = Buffer.concat([cipher.update(uint8ArrayToBuffer(data)), cipher.final()]);
53
+ const authTag = cipher.getAuthTag();
54
+ const ciphertext = Buffer.concat([encrypted, authTag]);
55
+ return {
56
+ ciphertext: bufferToUint8Array(ciphertext),
57
+ iv,
58
+ secretKey: key
59
+ };
60
+ }
61
+ async function decryptAESGCM(data, key, iv) {
62
+ if (key.length !== 32) throw new Error("Invalid key length. AES-256-GCM requires a 32-byte key.");
63
+ if (iv.length !== 12) throw new Error("Invalid IV length. AES-256-GCM requires a 12-byte IV.");
64
+ let dataBuffer;
65
+ if (typeof data === "string") dataBuffer = Buffer.from(data, "base64");
66
+ else dataBuffer = data;
67
+ const encryptedBuffer = Buffer.from(dataBuffer.buffer, dataBuffer.byteOffset, dataBuffer.byteLength);
68
+ const authTag = new Uint8Array(encryptedBuffer.buffer.slice(encryptedBuffer.byteOffset + encryptedBuffer.length - 16, encryptedBuffer.byteOffset + encryptedBuffer.length));
69
+ const encryptedContent = new Uint8Array(encryptedBuffer.buffer.slice(encryptedBuffer.byteOffset, encryptedBuffer.byteOffset + encryptedBuffer.length - 16));
70
+ const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
71
+ decipher.setAuthTag(authTag);
72
+ const decrypted = Buffer.concat([decipher.update(encryptedContent), decipher.final()]);
73
+ return new Uint8Array(decrypted.buffer, decrypted.byteOffset, decrypted.byteLength);
74
+ }
75
+ async function decryptDerivedAESGCM(keyPhrase, encryptedData) {
76
+ if (encryptedData.algorithm !== AES_GCM_DERIVED_ALGORITHM) throwWithCode(`${encryptedData.algorithm}" algorithm not implemented`, Err.UNIMPLEMENTED);
77
+ const { key, iv } = await deriveKeyAndIV(keyPhrase);
78
+ const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
79
+ return decryptAESGCM(ciphertext, key, iv);
80
+ }
81
+
82
+ //#endregion
83
+ export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["uint8Array: Uint8Array","base64: string","buffer: Buffer","seedBuffer: Uint8Array","length: number","keyPhrase: string | Uint8Array","keyBuffer: Uint8Array","data: Uint8Array","key?: Uint8Array","iv?: Uint8Array","data: Uint8Array | string","key: Uint8Array","iv: Uint8Array","dataBuffer: Uint8Array","keyPhrase: string","encryptedData: EncryptedData"],"sources":["../../src/node/index.ts"],"sourcesContent":["import { throwWithCode } from '@towns-protocol/dlog'\nimport { EncryptedData, Err } from '@towns-protocol/proto'\nimport { AES_GCM_DERIVED_ALGORITHM } from '@towns-protocol/encryption'\nimport crypto from 'node:crypto'\n\nexport function uint8ArrayToBase64(uint8Array: Uint8Array): string {\n return Buffer.from(uint8Array).toString('base64')\n}\n\nexport function base64ToUint8Array(base64: string): Uint8Array {\n const buffer = Buffer.from(base64, 'base64')\n return new Uint8Array(buffer)\n}\n\nfunction bufferToUint8Array(buffer: Buffer): Uint8Array {\n return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)\n}\n\nfunction uint8ArrayToBuffer(uint8Array: Uint8Array): Buffer {\n return Buffer.from(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength)\n}\n\nasync function getExtendedKeyMaterial(seedBuffer: Uint8Array, length: number): Promise<Uint8Array> {\n const hash = crypto.createHash('sha256')\n hash.update(uint8ArrayToBuffer(seedBuffer))\n let keyMaterial = bufferToUint8Array(hash.digest())\n\n while (keyMaterial.length < length) {\n const newHash = crypto.createHash('sha256')\n newHash.update(uint8ArrayToBuffer(keyMaterial))\n keyMaterial = new Uint8Array([...keyMaterial, ...bufferToUint8Array(newHash.digest())])\n }\n\n return keyMaterial.slice(0, length)\n}\n\nexport async function deriveKeyAndIV(\n keyPhrase: string | Uint8Array,\n): Promise<{ key: Uint8Array; iv: Uint8Array }> {\n let keyBuffer: Uint8Array\n\n if (typeof keyPhrase === 'string') {\n const encoder = new TextEncoder()\n keyBuffer = encoder.encode(keyPhrase)\n } else {\n keyBuffer = keyPhrase\n }\n\n const keyMaterial = await getExtendedKeyMaterial(keyBuffer, 32 + 12) // 32 bytes for key, 12 bytes for IV\n\n const key = keyMaterial.slice(0, 32) // AES-256 key\n const iv = keyMaterial.slice(32, 32 + 12) // AES-GCM IV\n\n return { key, iv }\n}\n\nexport async function encryptAESGCM(\n data: Uint8Array,\n key?: Uint8Array,\n iv?: Uint8Array,\n): Promise<{ ciphertext: Uint8Array; iv: Uint8Array; secretKey: Uint8Array }> {\n if (!data || data.length === 0) {\n throw new Error('Cannot encrypt undefined or empty data')\n }\n\n if (!key) {\n key = crypto.randomBytes(32)\n } else if (key.length !== 32) {\n throw new Error('Invalid key length. AES-256-GCM requires a 32-byte key.')\n }\n\n if (!iv) {\n iv = crypto.randomBytes(12)\n } else if (iv.length !== 12) {\n throw new Error('Invalid IV length. AES-256-GCM requires a 12-byte IV.')\n }\n\n const cipher = crypto.createCipheriv(\n 'aes-256-gcm',\n uint8ArrayToBuffer(key),\n uint8ArrayToBuffer(iv),\n )\n const encrypted = Buffer.concat([cipher.update(uint8ArrayToBuffer(data)), cipher.final()])\n const authTag = cipher.getAuthTag()\n const ciphertext = Buffer.concat([encrypted, authTag])\n\n return { ciphertext: bufferToUint8Array(ciphertext), iv, secretKey: key }\n}\n\nexport async function decryptAESGCM(\n data: Uint8Array | string,\n key: Uint8Array,\n iv: Uint8Array,\n): Promise<Uint8Array> {\n if (key.length !== 32) {\n throw new Error('Invalid key length. AES-256-GCM requires a 32-byte key.')\n }\n\n if (iv.length !== 12) {\n throw new Error('Invalid IV length. AES-256-GCM requires a 12-byte IV.')\n }\n\n // Convert data to Uint8Array if it is a string\n let dataBuffer: Uint8Array\n if (typeof data === 'string') {\n dataBuffer = Buffer.from(data, 'base64')\n } else {\n dataBuffer = data\n }\n\n const encryptedBuffer = Buffer.from(\n dataBuffer.buffer,\n dataBuffer.byteOffset,\n dataBuffer.byteLength,\n )\n const authTag = new Uint8Array(\n encryptedBuffer.buffer.slice(\n encryptedBuffer.byteOffset + encryptedBuffer.length - 16,\n encryptedBuffer.byteOffset + encryptedBuffer.length,\n ),\n )\n const encryptedContent = new Uint8Array(\n encryptedBuffer.buffer.slice(\n encryptedBuffer.byteOffset,\n encryptedBuffer.byteOffset + encryptedBuffer.length - 16,\n ),\n )\n\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv)\n decipher.setAuthTag(authTag)\n\n const decrypted = Buffer.concat([decipher.update(encryptedContent), decipher.final()])\n return new Uint8Array(decrypted.buffer, decrypted.byteOffset, decrypted.byteLength)\n}\n\nexport async function decryptDerivedAESGCM(\n keyPhrase: string,\n encryptedData: EncryptedData,\n): Promise<Uint8Array> {\n if (encryptedData.algorithm !== AES_GCM_DERIVED_ALGORITHM) {\n throwWithCode(`${encryptedData.algorithm}\" algorithm not implemented`, Err.UNIMPLEMENTED)\n }\n const { key, iv } = await deriveKeyAndIV(keyPhrase)\n const ciphertext = base64ToUint8Array(encryptedData.ciphertext)\n return decryptAESGCM(ciphertext, key, iv)\n}\n"],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ const require_chunk = require('../chunk-CUT6urMc.cjs');
2
+ const __towns_protocol_dlog = require_chunk.__toESM(require("@towns-protocol/dlog"));
3
+ const __towns_protocol_proto = require_chunk.__toESM(require("@towns-protocol/proto"));
4
+ const __towns_protocol_encryption = require_chunk.__toESM(require("@towns-protocol/encryption"));
5
+
6
+ //#region src/web/index.ts
7
+ function uint8ArrayToBase64(uint8Array) {
8
+ const binary = Array.from(uint8Array, (byte) => String.fromCharCode(byte)).join("");
9
+ return btoa(binary);
10
+ }
11
+ function base64ToUint8Array(base64) {
12
+ const binary = atob(base64);
13
+ return new Uint8Array(Array.from(binary, (char) => char.charCodeAt(0)));
14
+ }
15
+ async function getExtendedKeyMaterial(seedBuffer, length) {
16
+ let keyMaterial = new Uint8Array(await crypto.subtle.digest("SHA-256", seedBuffer));
17
+ while (keyMaterial.length < length) {
18
+ const newHash = new Uint8Array(await crypto.subtle.digest("SHA-256", keyMaterial));
19
+ const combined = new Uint8Array(keyMaterial.length + newHash.length);
20
+ combined.set(keyMaterial);
21
+ combined.set(newHash, keyMaterial.length);
22
+ keyMaterial = combined;
23
+ }
24
+ return keyMaterial.slice(0, length);
25
+ }
26
+ async function deriveKeyAndIV(keyPhrase) {
27
+ let keyBuffer;
28
+ if (typeof keyPhrase === "string") {
29
+ const encoder = new TextEncoder();
30
+ keyBuffer = encoder.encode(keyPhrase);
31
+ } else keyBuffer = keyPhrase;
32
+ const keyMaterial = await getExtendedKeyMaterial(keyBuffer, 44);
33
+ const key = keyMaterial.slice(0, 32);
34
+ const iv = keyMaterial.slice(32, 44);
35
+ return {
36
+ key,
37
+ iv
38
+ };
39
+ }
40
+ async function encryptAESGCM(data, key, iv) {
41
+ if (!data || data.length === 0) throw new Error("Cannot encrypt undefined or empty data");
42
+ if (!key) {
43
+ key = new Uint8Array(32);
44
+ crypto.getRandomValues(key);
45
+ } else if (key.length !== 32) throw new Error("Invalid key length. AES-256-GCM requires a 32-byte key.");
46
+ if (!iv) {
47
+ iv = new Uint8Array(12);
48
+ crypto.getRandomValues(iv);
49
+ } else if (iv.length !== 12) throw new Error("Invalid IV length. AES-256-GCM requires a 12-byte IV.");
50
+ const cryptoKey = await crypto.subtle.importKey("raw", key, { name: "AES-GCM" }, false, ["encrypt"]);
51
+ const encryptedBuffer = await crypto.subtle.encrypt({
52
+ name: "AES-GCM",
53
+ iv
54
+ }, cryptoKey, data);
55
+ const ciphertext = new Uint8Array(encryptedBuffer);
56
+ return {
57
+ ciphertext,
58
+ iv,
59
+ secretKey: key
60
+ };
61
+ }
62
+ async function decryptAESGCM(data, key, iv) {
63
+ if (key.length !== 32) throw new Error("Invalid key length. AES-256-GCM requires a 32-byte key.");
64
+ if (iv.length !== 12) throw new Error("Invalid IV length. AES-256-GCM requires a 12-byte IV.");
65
+ let dataBuffer;
66
+ if (typeof data === "string") dataBuffer = base64ToUint8Array(data);
67
+ else dataBuffer = data;
68
+ const cryptoKey = await crypto.subtle.importKey("raw", key, { name: "AES-GCM" }, false, ["decrypt"]);
69
+ const decryptedBuffer = await crypto.subtle.decrypt({
70
+ name: "AES-GCM",
71
+ iv
72
+ }, cryptoKey, dataBuffer);
73
+ return new Uint8Array(decryptedBuffer);
74
+ }
75
+ async function decryptDerivedAESGCM(keyPhrase, encryptedData) {
76
+ if (encryptedData.algorithm !== __towns_protocol_encryption.AES_GCM_DERIVED_ALGORITHM) (0, __towns_protocol_dlog.throwWithCode)(`${encryptedData.algorithm}" algorithm not implemented`, __towns_protocol_proto.Err.UNIMPLEMENTED);
77
+ const { key, iv } = await deriveKeyAndIV(keyPhrase);
78
+ const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
79
+ return decryptAESGCM(ciphertext, key, iv);
80
+ }
81
+
82
+ //#endregion
83
+ exports.base64ToUint8Array = base64ToUint8Array;
84
+ exports.decryptAESGCM = decryptAESGCM;
85
+ exports.decryptDerivedAESGCM = decryptDerivedAESGCM;
86
+ exports.deriveKeyAndIV = deriveKeyAndIV;
87
+ exports.encryptAESGCM = encryptAESGCM;
88
+ exports.uint8ArrayToBase64 = uint8ArrayToBase64;
89
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["uint8Array: Uint8Array","base64: string","seedBuffer: Uint8Array","length: number","keyPhrase: string | Uint8Array","keyBuffer: Uint8Array","data: Uint8Array","key?: Uint8Array","iv?: Uint8Array","data: Uint8Array | string","key: Uint8Array","iv: Uint8Array","dataBuffer: Uint8Array","keyPhrase: string","encryptedData: EncryptedData","AES_GCM_DERIVED_ALGORITHM","Err"],"sources":["../../src/web/index.ts"],"sourcesContent":["import { throwWithCode } from '@towns-protocol/dlog'\nimport { EncryptedData, Err } from '@towns-protocol/proto'\nimport { AES_GCM_DERIVED_ALGORITHM } from '@towns-protocol/encryption'\n\nexport function uint8ArrayToBase64(uint8Array: Uint8Array): string {\n const binary = Array.from(uint8Array, (byte) => String.fromCharCode(byte)).join('')\n return btoa(binary)\n}\n\nexport function base64ToUint8Array(base64: string): Uint8Array {\n const binary = atob(base64)\n return new Uint8Array(Array.from(binary, (char) => char.charCodeAt(0)))\n}\n\nasync function getExtendedKeyMaterial(seedBuffer: Uint8Array, length: number): Promise<Uint8Array> {\n let keyMaterial = new Uint8Array(await crypto.subtle.digest('SHA-256', seedBuffer))\n\n while (keyMaterial.length < length) {\n const newHash = new Uint8Array(await crypto.subtle.digest('SHA-256', keyMaterial))\n const combined = new Uint8Array(keyMaterial.length + newHash.length)\n combined.set(keyMaterial)\n combined.set(newHash, keyMaterial.length)\n keyMaterial = combined\n }\n\n return keyMaterial.slice(0, length)\n}\n\nexport async function deriveKeyAndIV(\n keyPhrase: string | Uint8Array,\n): Promise<{ key: Uint8Array; iv: Uint8Array }> {\n let keyBuffer: Uint8Array\n\n if (typeof keyPhrase === 'string') {\n const encoder = new TextEncoder()\n keyBuffer = encoder.encode(keyPhrase)\n } else {\n keyBuffer = keyPhrase\n }\n\n const keyMaterial = await getExtendedKeyMaterial(keyBuffer, 32 + 12) // 32 bytes for key, 12 bytes for IV\n\n const key = keyMaterial.slice(0, 32) // AES-256 key\n const iv = keyMaterial.slice(32, 32 + 12) // AES-GCM IV\n\n return { key, iv }\n}\n\nexport async function encryptAESGCM(\n data: Uint8Array,\n key?: Uint8Array,\n iv?: Uint8Array,\n): Promise<{ ciphertext: Uint8Array; iv: Uint8Array; secretKey: Uint8Array }> {\n if (!data || data.length === 0) {\n throw new Error('Cannot encrypt undefined or empty data')\n }\n\n if (!key) {\n key = new Uint8Array(32)\n crypto.getRandomValues(key)\n } else if (key.length !== 32) {\n throw new Error('Invalid key length. AES-256-GCM requires a 32-byte key.')\n }\n\n if (!iv) {\n iv = new Uint8Array(12)\n crypto.getRandomValues(iv)\n } else if (iv.length !== 12) {\n throw new Error('Invalid IV length. AES-256-GCM requires a 12-byte IV.')\n }\n\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-GCM' }, false, [\n 'encrypt',\n ])\n\n const encryptedBuffer = await crypto.subtle.encrypt(\n {\n name: 'AES-GCM',\n iv: iv,\n },\n cryptoKey,\n data,\n )\n\n const ciphertext = new Uint8Array(encryptedBuffer)\n\n return { ciphertext, iv, secretKey: key }\n}\n\nexport async function decryptAESGCM(\n data: Uint8Array | string,\n key: Uint8Array,\n iv: Uint8Array,\n): Promise<Uint8Array> {\n if (key.length !== 32) {\n throw new Error('Invalid key length. AES-256-GCM requires a 32-byte key.')\n }\n\n if (iv.length !== 12) {\n throw new Error('Invalid IV length. AES-256-GCM requires a 12-byte IV.')\n }\n\n let dataBuffer: Uint8Array\n if (typeof data === 'string') {\n dataBuffer = base64ToUint8Array(data)\n } else {\n dataBuffer = data\n }\n\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-GCM' }, false, [\n 'decrypt',\n ])\n\n const decryptedBuffer = await crypto.subtle.decrypt(\n {\n name: 'AES-GCM',\n iv: iv,\n },\n cryptoKey,\n dataBuffer,\n )\n\n return new Uint8Array(decryptedBuffer)\n}\n\nexport async function decryptDerivedAESGCM(\n keyPhrase: string,\n encryptedData: EncryptedData,\n): Promise<Uint8Array> {\n if (encryptedData.algorithm !== AES_GCM_DERIVED_ALGORITHM) {\n throwWithCode(`${encryptedData.algorithm}\" algorithm not implemented`, Err.UNIMPLEMENTED)\n }\n const { key, iv } = await deriveKeyAndIV(keyPhrase)\n const ciphertext = base64ToUint8Array(encryptedData.ciphertext)\n return decryptAESGCM(ciphertext, key, iv)\n}\n"],"mappings":";;;;;;AAIA,SAAgB,mBAAmBA,YAAgC;CAC/D,MAAM,SAAS,MAAM,KAAK,YAAY,CAAC,SAAS,OAAO,aAAa,KAAK,CAAC,CAAC,KAAK,GAAG;AACnF,QAAO,KAAK,OAAO;AACtB;AAED,SAAgB,mBAAmBC,QAA4B;CAC3D,MAAM,SAAS,KAAK,OAAO;AAC3B,QAAO,IAAI,WAAW,MAAM,KAAK,QAAQ,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;AACzE;AAED,eAAe,uBAAuBC,YAAwBC,QAAqC;CAC/F,IAAI,cAAc,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,WAAW;AAElF,QAAO,YAAY,SAAS,QAAQ;EAChC,MAAM,UAAU,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,YAAY;EACjF,MAAM,WAAW,IAAI,WAAW,YAAY,SAAS,QAAQ;AAC7D,WAAS,IAAI,YAAY;AACzB,WAAS,IAAI,SAAS,YAAY,OAAO;AACzC,gBAAc;CACjB;AAED,QAAO,YAAY,MAAM,GAAG,OAAO;AACtC;AAED,eAAsB,eAClBC,WAC4C;CAC5C,IAAIC;AAEJ,YAAW,cAAc,UAAU;EAC/B,MAAM,UAAU,IAAI;AACpB,cAAY,QAAQ,OAAO,UAAU;CACxC,MACG,aAAY;CAGhB,MAAM,cAAc,MAAM,uBAAuB,WAAW,GAAQ;CAEpE,MAAM,MAAM,YAAY,MAAM,GAAG,GAAG;CACpC,MAAM,KAAK,YAAY,MAAM,IAAI,GAAQ;AAEzC,QAAO;EAAE;EAAK;CAAI;AACrB;AAED,eAAsB,cAClBC,MACAC,KACAC,IAC0E;AAC1E,MAAK,QAAQ,KAAK,WAAW,EACzB,OAAM,IAAI,MAAM;AAGpB,MAAK,KAAK;AACN,QAAM,IAAI,WAAW;AACrB,SAAO,gBAAgB,IAAI;CAC9B,WAAU,IAAI,WAAW,GACtB,OAAM,IAAI,MAAM;AAGpB,MAAK,IAAI;AACL,OAAK,IAAI,WAAW;AACpB,SAAO,gBAAgB,GAAG;CAC7B,WAAU,GAAG,WAAW,GACrB,OAAM,IAAI,MAAM;CAGpB,MAAM,YAAY,MAAM,OAAO,OAAO,UAAU,OAAO,KAAK,EAAE,MAAM,UAAW,GAAE,OAAO,CACpF,SACH,EAAC;CAEF,MAAM,kBAAkB,MAAM,OAAO,OAAO,QACxC;EACI,MAAM;EACF;CACP,GACD,WACA,KACH;CAED,MAAM,aAAa,IAAI,WAAW;AAElC,QAAO;EAAE;EAAY;EAAI,WAAW;CAAK;AAC5C;AAED,eAAsB,cAClBC,MACAC,KACAC,IACmB;AACnB,KAAI,IAAI,WAAW,GACf,OAAM,IAAI,MAAM;AAGpB,KAAI,GAAG,WAAW,GACd,OAAM,IAAI,MAAM;CAGpB,IAAIC;AACJ,YAAW,SAAS,SAChB,cAAa,mBAAmB,KAAK;KAErC,cAAa;CAGjB,MAAM,YAAY,MAAM,OAAO,OAAO,UAAU,OAAO,KAAK,EAAE,MAAM,UAAW,GAAE,OAAO,CACpF,SACH,EAAC;CAEF,MAAM,kBAAkB,MAAM,OAAO,OAAO,QACxC;EACI,MAAM;EACF;CACP,GACD,WACA,WACH;AAED,QAAO,IAAI,WAAW;AACzB;AAED,eAAsB,qBAClBC,WACAC,eACmB;AACnB,KAAI,cAAc,cAAcC,sDAC5B,2CAAe,EAAE,cAAc,UAAU,8BAA8BC,2BAAI,cAAc;CAE7F,MAAM,EAAE,KAAK,IAAI,GAAG,MAAM,eAAe,UAAU;CACnD,MAAM,aAAa,mBAAmB,cAAc,WAAW;AAC/D,QAAO,cAAc,YAAY,KAAK,GAAG;AAC5C"}
@@ -0,0 +1,21 @@
1
+ import { EncryptedData } from "@towns-protocol/proto";
2
+
3
+ //#region src/web/index.d.ts
4
+ declare function uint8ArrayToBase64(uint8Array: Uint8Array): string;
5
+ declare function base64ToUint8Array(base64: string): Uint8Array;
6
+ declare function deriveKeyAndIV(keyPhrase: string | Uint8Array): Promise<{
7
+ key: Uint8Array;
8
+ iv: Uint8Array;
9
+ }>;
10
+ declare function encryptAESGCM(data: Uint8Array, key?: Uint8Array, iv?: Uint8Array): Promise<{
11
+ ciphertext: Uint8Array;
12
+ iv: Uint8Array;
13
+ secretKey: Uint8Array;
14
+ }>;
15
+ declare function decryptAESGCM(data: Uint8Array | string, key: Uint8Array, iv: Uint8Array): Promise<Uint8Array>;
16
+ declare function decryptDerivedAESGCM(keyPhrase: string, encryptedData: EncryptedData): Promise<Uint8Array>;
17
+ //# sourceMappingURL=index.d.ts.map
18
+
19
+ //#endregion
20
+ export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
21
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/web/index.ts"],"sourcesContent":[],"mappings":";;;iBAIgB,kBAAA,aAA+B;iBAK/B,kBAAA,kBAAoC;AALpC,iBAwBM,cAAA,CAxByB,SAAU,EAAA,MAAA,GAyBjC,UAzBiC,CAAA,EA0BtD,OA1BsD,CAAA;EAKzC,GAAA,EAqBE,UArBF;EAmBM,EAAA,EAEY,UAFZ;CAAc,CAAA;AACZ,iBAmBF,aAAA,CAnBE,IAAA,EAoBd,UApBc,EAAA,GAAA,CAAA,EAqBd,UArBc,EAAA,EAAA,CAAA,EAsBf,UAtBe,CAAA,EAuBrB,OAvBqB,CAAA;EAAU,UAChB,EAsBO,UAtBP;EAAU,EAAA,EAsBa,UAtBP;EAAU,SAAzC,EAsB6D,UAtB7D;AAAO,CAAA,CAAA;AAkBY,iBAyCA,aAAA,CAzCa,IAAA,EA0CzB,UA1CyB,GAAA,MAAA,EAAA,GAAA,EA2C1B,UA3C0B,EAAA,EAAA,EA4C3B,UA5C2B,CAAA,EA6ChC,OA7CgC,CA6CxB,UA7CwB,CAAA;AAAA,iBA6Eb,oBAAA,CA7Ea,SAAA,EAAA,MAAA,EAAA,aAAA,EA+EhB,aA/EgB,CAAA,EAgFhC,OAhFgC,CAgFxB,UAhFwB,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { EncryptedData } from "@towns-protocol/proto";
2
+
3
+ //#region src/web/index.d.ts
4
+ declare function uint8ArrayToBase64(uint8Array: Uint8Array): string;
5
+ declare function base64ToUint8Array(base64: string): Uint8Array;
6
+ declare function deriveKeyAndIV(keyPhrase: string | Uint8Array): Promise<{
7
+ key: Uint8Array;
8
+ iv: Uint8Array;
9
+ }>;
10
+ declare function encryptAESGCM(data: Uint8Array, key?: Uint8Array, iv?: Uint8Array): Promise<{
11
+ ciphertext: Uint8Array;
12
+ iv: Uint8Array;
13
+ secretKey: Uint8Array;
14
+ }>;
15
+ declare function decryptAESGCM(data: Uint8Array | string, key: Uint8Array, iv: Uint8Array): Promise<Uint8Array>;
16
+ declare function decryptDerivedAESGCM(keyPhrase: string, encryptedData: EncryptedData): Promise<Uint8Array>;
17
+ //# sourceMappingURL=index.d.ts.map
18
+
19
+ //#endregion
20
+ export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/web/index.ts"],"sourcesContent":[],"mappings":";;;iBAIgB,kBAAA,aAA+B;iBAK/B,kBAAA,kBAAoC;AALpC,iBAwBM,cAAA,CAxByB,SAAU,EAAA,MAAA,GAyBjC,UAzBiC,CAAA,EA0BtD,OA1BsD,CAAA;EAKzC,GAAA,EAqBE,UArBF;EAmBM,EAAA,EAEY,UAFZ;CAAc,CAAA;AACZ,iBAmBF,aAAA,CAnBE,IAAA,EAoBd,UApBc,EAAA,GAAA,CAAA,EAqBd,UArBc,EAAA,EAAA,CAAA,EAsBf,UAtBe,CAAA,EAuBrB,OAvBqB,CAAA;EAAU,UAChB,EAsBO,UAtBP;EAAU,EAAA,EAsBa,UAtBP;EAAU,SAAzC,EAsB6D,UAtB7D;AAAO,CAAA,CAAA;AAkBY,iBAyCA,aAAA,CAzCa,IAAA,EA0CzB,UA1CyB,GAAA,MAAA,EAAA,GAAA,EA2C1B,UA3C0B,EAAA,EAAA,EA4C3B,UA5C2B,CAAA,EA6ChC,OA7CgC,CA6CxB,UA7CwB,CAAA;AAAA,iBA6Eb,oBAAA,CA7Ea,SAAA,EAAA,MAAA,EAAA,aAAA,EA+EhB,aA/EgB,CAAA,EAgFhC,OAhFgC,CAgFxB,UAhFwB,CAAA"}
@@ -0,0 +1,83 @@
1
+ import { throwWithCode } from "@towns-protocol/dlog";
2
+ import { Err } from "@towns-protocol/proto";
3
+ import { AES_GCM_DERIVED_ALGORITHM } from "@towns-protocol/encryption";
4
+
5
+ //#region src/web/index.ts
6
+ function uint8ArrayToBase64(uint8Array) {
7
+ const binary = Array.from(uint8Array, (byte) => String.fromCharCode(byte)).join("");
8
+ return btoa(binary);
9
+ }
10
+ function base64ToUint8Array(base64) {
11
+ const binary = atob(base64);
12
+ return new Uint8Array(Array.from(binary, (char) => char.charCodeAt(0)));
13
+ }
14
+ async function getExtendedKeyMaterial(seedBuffer, length) {
15
+ let keyMaterial = new Uint8Array(await crypto.subtle.digest("SHA-256", seedBuffer));
16
+ while (keyMaterial.length < length) {
17
+ const newHash = new Uint8Array(await crypto.subtle.digest("SHA-256", keyMaterial));
18
+ const combined = new Uint8Array(keyMaterial.length + newHash.length);
19
+ combined.set(keyMaterial);
20
+ combined.set(newHash, keyMaterial.length);
21
+ keyMaterial = combined;
22
+ }
23
+ return keyMaterial.slice(0, length);
24
+ }
25
+ async function deriveKeyAndIV(keyPhrase) {
26
+ let keyBuffer;
27
+ if (typeof keyPhrase === "string") {
28
+ const encoder = new TextEncoder();
29
+ keyBuffer = encoder.encode(keyPhrase);
30
+ } else keyBuffer = keyPhrase;
31
+ const keyMaterial = await getExtendedKeyMaterial(keyBuffer, 44);
32
+ const key = keyMaterial.slice(0, 32);
33
+ const iv = keyMaterial.slice(32, 44);
34
+ return {
35
+ key,
36
+ iv
37
+ };
38
+ }
39
+ async function encryptAESGCM(data, key, iv) {
40
+ if (!data || data.length === 0) throw new Error("Cannot encrypt undefined or empty data");
41
+ if (!key) {
42
+ key = new Uint8Array(32);
43
+ crypto.getRandomValues(key);
44
+ } else if (key.length !== 32) throw new Error("Invalid key length. AES-256-GCM requires a 32-byte key.");
45
+ if (!iv) {
46
+ iv = new Uint8Array(12);
47
+ crypto.getRandomValues(iv);
48
+ } else if (iv.length !== 12) throw new Error("Invalid IV length. AES-256-GCM requires a 12-byte IV.");
49
+ const cryptoKey = await crypto.subtle.importKey("raw", key, { name: "AES-GCM" }, false, ["encrypt"]);
50
+ const encryptedBuffer = await crypto.subtle.encrypt({
51
+ name: "AES-GCM",
52
+ iv
53
+ }, cryptoKey, data);
54
+ const ciphertext = new Uint8Array(encryptedBuffer);
55
+ return {
56
+ ciphertext,
57
+ iv,
58
+ secretKey: key
59
+ };
60
+ }
61
+ async function decryptAESGCM(data, key, iv) {
62
+ if (key.length !== 32) throw new Error("Invalid key length. AES-256-GCM requires a 32-byte key.");
63
+ if (iv.length !== 12) throw new Error("Invalid IV length. AES-256-GCM requires a 12-byte IV.");
64
+ let dataBuffer;
65
+ if (typeof data === "string") dataBuffer = base64ToUint8Array(data);
66
+ else dataBuffer = data;
67
+ const cryptoKey = await crypto.subtle.importKey("raw", key, { name: "AES-GCM" }, false, ["decrypt"]);
68
+ const decryptedBuffer = await crypto.subtle.decrypt({
69
+ name: "AES-GCM",
70
+ iv
71
+ }, cryptoKey, dataBuffer);
72
+ return new Uint8Array(decryptedBuffer);
73
+ }
74
+ async function decryptDerivedAESGCM(keyPhrase, encryptedData) {
75
+ if (encryptedData.algorithm !== AES_GCM_DERIVED_ALGORITHM) throwWithCode(`${encryptedData.algorithm}" algorithm not implemented`, Err.UNIMPLEMENTED);
76
+ const { key, iv } = await deriveKeyAndIV(keyPhrase);
77
+ const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
78
+ return decryptAESGCM(ciphertext, key, iv);
79
+ }
80
+
81
+ //#endregion
82
+ export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["uint8Array: Uint8Array","base64: string","seedBuffer: Uint8Array","length: number","keyPhrase: string | Uint8Array","keyBuffer: Uint8Array","data: Uint8Array","key?: Uint8Array","iv?: Uint8Array","data: Uint8Array | string","key: Uint8Array","iv: Uint8Array","dataBuffer: Uint8Array","keyPhrase: string","encryptedData: EncryptedData"],"sources":["../../src/web/index.ts"],"sourcesContent":["import { throwWithCode } from '@towns-protocol/dlog'\nimport { EncryptedData, Err } from '@towns-protocol/proto'\nimport { AES_GCM_DERIVED_ALGORITHM } from '@towns-protocol/encryption'\n\nexport function uint8ArrayToBase64(uint8Array: Uint8Array): string {\n const binary = Array.from(uint8Array, (byte) => String.fromCharCode(byte)).join('')\n return btoa(binary)\n}\n\nexport function base64ToUint8Array(base64: string): Uint8Array {\n const binary = atob(base64)\n return new Uint8Array(Array.from(binary, (char) => char.charCodeAt(0)))\n}\n\nasync function getExtendedKeyMaterial(seedBuffer: Uint8Array, length: number): Promise<Uint8Array> {\n let keyMaterial = new Uint8Array(await crypto.subtle.digest('SHA-256', seedBuffer))\n\n while (keyMaterial.length < length) {\n const newHash = new Uint8Array(await crypto.subtle.digest('SHA-256', keyMaterial))\n const combined = new Uint8Array(keyMaterial.length + newHash.length)\n combined.set(keyMaterial)\n combined.set(newHash, keyMaterial.length)\n keyMaterial = combined\n }\n\n return keyMaterial.slice(0, length)\n}\n\nexport async function deriveKeyAndIV(\n keyPhrase: string | Uint8Array,\n): Promise<{ key: Uint8Array; iv: Uint8Array }> {\n let keyBuffer: Uint8Array\n\n if (typeof keyPhrase === 'string') {\n const encoder = new TextEncoder()\n keyBuffer = encoder.encode(keyPhrase)\n } else {\n keyBuffer = keyPhrase\n }\n\n const keyMaterial = await getExtendedKeyMaterial(keyBuffer, 32 + 12) // 32 bytes for key, 12 bytes for IV\n\n const key = keyMaterial.slice(0, 32) // AES-256 key\n const iv = keyMaterial.slice(32, 32 + 12) // AES-GCM IV\n\n return { key, iv }\n}\n\nexport async function encryptAESGCM(\n data: Uint8Array,\n key?: Uint8Array,\n iv?: Uint8Array,\n): Promise<{ ciphertext: Uint8Array; iv: Uint8Array; secretKey: Uint8Array }> {\n if (!data || data.length === 0) {\n throw new Error('Cannot encrypt undefined or empty data')\n }\n\n if (!key) {\n key = new Uint8Array(32)\n crypto.getRandomValues(key)\n } else if (key.length !== 32) {\n throw new Error('Invalid key length. AES-256-GCM requires a 32-byte key.')\n }\n\n if (!iv) {\n iv = new Uint8Array(12)\n crypto.getRandomValues(iv)\n } else if (iv.length !== 12) {\n throw new Error('Invalid IV length. AES-256-GCM requires a 12-byte IV.')\n }\n\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-GCM' }, false, [\n 'encrypt',\n ])\n\n const encryptedBuffer = await crypto.subtle.encrypt(\n {\n name: 'AES-GCM',\n iv: iv,\n },\n cryptoKey,\n data,\n )\n\n const ciphertext = new Uint8Array(encryptedBuffer)\n\n return { ciphertext, iv, secretKey: key }\n}\n\nexport async function decryptAESGCM(\n data: Uint8Array | string,\n key: Uint8Array,\n iv: Uint8Array,\n): Promise<Uint8Array> {\n if (key.length !== 32) {\n throw new Error('Invalid key length. AES-256-GCM requires a 32-byte key.')\n }\n\n if (iv.length !== 12) {\n throw new Error('Invalid IV length. AES-256-GCM requires a 12-byte IV.')\n }\n\n let dataBuffer: Uint8Array\n if (typeof data === 'string') {\n dataBuffer = base64ToUint8Array(data)\n } else {\n dataBuffer = data\n }\n\n const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-GCM' }, false, [\n 'decrypt',\n ])\n\n const decryptedBuffer = await crypto.subtle.decrypt(\n {\n name: 'AES-GCM',\n iv: iv,\n },\n cryptoKey,\n dataBuffer,\n )\n\n return new Uint8Array(decryptedBuffer)\n}\n\nexport async function decryptDerivedAESGCM(\n keyPhrase: string,\n encryptedData: EncryptedData,\n): Promise<Uint8Array> {\n if (encryptedData.algorithm !== AES_GCM_DERIVED_ALGORITHM) {\n throwWithCode(`${encryptedData.algorithm}\" algorithm not implemented`, Err.UNIMPLEMENTED)\n }\n const { key, iv } = await deriveKeyAndIV(keyPhrase)\n const ciphertext = base64ToUint8Array(encryptedData.ciphertext)\n return decryptAESGCM(ciphertext, key, iv)\n}\n"],"mappings":";;;;;AAIA,SAAgB,mBAAmBA,YAAgC;CAC/D,MAAM,SAAS,MAAM,KAAK,YAAY,CAAC,SAAS,OAAO,aAAa,KAAK,CAAC,CAAC,KAAK,GAAG;AACnF,QAAO,KAAK,OAAO;AACtB;AAED,SAAgB,mBAAmBC,QAA4B;CAC3D,MAAM,SAAS,KAAK,OAAO;AAC3B,QAAO,IAAI,WAAW,MAAM,KAAK,QAAQ,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;AACzE;AAED,eAAe,uBAAuBC,YAAwBC,QAAqC;CAC/F,IAAI,cAAc,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,WAAW;AAElF,QAAO,YAAY,SAAS,QAAQ;EAChC,MAAM,UAAU,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,YAAY;EACjF,MAAM,WAAW,IAAI,WAAW,YAAY,SAAS,QAAQ;AAC7D,WAAS,IAAI,YAAY;AACzB,WAAS,IAAI,SAAS,YAAY,OAAO;AACzC,gBAAc;CACjB;AAED,QAAO,YAAY,MAAM,GAAG,OAAO;AACtC;AAED,eAAsB,eAClBC,WAC4C;CAC5C,IAAIC;AAEJ,YAAW,cAAc,UAAU;EAC/B,MAAM,UAAU,IAAI;AACpB,cAAY,QAAQ,OAAO,UAAU;CACxC,MACG,aAAY;CAGhB,MAAM,cAAc,MAAM,uBAAuB,WAAW,GAAQ;CAEpE,MAAM,MAAM,YAAY,MAAM,GAAG,GAAG;CACpC,MAAM,KAAK,YAAY,MAAM,IAAI,GAAQ;AAEzC,QAAO;EAAE;EAAK;CAAI;AACrB;AAED,eAAsB,cAClBC,MACAC,KACAC,IAC0E;AAC1E,MAAK,QAAQ,KAAK,WAAW,EACzB,OAAM,IAAI,MAAM;AAGpB,MAAK,KAAK;AACN,QAAM,IAAI,WAAW;AACrB,SAAO,gBAAgB,IAAI;CAC9B,WAAU,IAAI,WAAW,GACtB,OAAM,IAAI,MAAM;AAGpB,MAAK,IAAI;AACL,OAAK,IAAI,WAAW;AACpB,SAAO,gBAAgB,GAAG;CAC7B,WAAU,GAAG,WAAW,GACrB,OAAM,IAAI,MAAM;CAGpB,MAAM,YAAY,MAAM,OAAO,OAAO,UAAU,OAAO,KAAK,EAAE,MAAM,UAAW,GAAE,OAAO,CACpF,SACH,EAAC;CAEF,MAAM,kBAAkB,MAAM,OAAO,OAAO,QACxC;EACI,MAAM;EACF;CACP,GACD,WACA,KACH;CAED,MAAM,aAAa,IAAI,WAAW;AAElC,QAAO;EAAE;EAAY;EAAI,WAAW;CAAK;AAC5C;AAED,eAAsB,cAClBC,MACAC,KACAC,IACmB;AACnB,KAAI,IAAI,WAAW,GACf,OAAM,IAAI,MAAM;AAGpB,KAAI,GAAG,WAAW,GACd,OAAM,IAAI,MAAM;CAGpB,IAAIC;AACJ,YAAW,SAAS,SAChB,cAAa,mBAAmB,KAAK;KAErC,cAAa;CAGjB,MAAM,YAAY,MAAM,OAAO,OAAO,UAAU,OAAO,KAAK,EAAE,MAAM,UAAW,GAAE,OAAO,CACpF,SACH,EAAC;CAEF,MAAM,kBAAkB,MAAM,OAAO,OAAO,QACxC;EACI,MAAM;EACF;CACP,GACD,WACA,WACH;AAED,QAAO,IAAI,WAAW;AACzB;AAED,eAAsB,qBAClBC,WACAC,eACmB;AACnB,KAAI,cAAc,cAAc,0BAC5B,gBAAe,EAAE,cAAc,UAAU,8BAA8B,IAAI,cAAc;CAE7F,MAAM,EAAE,KAAK,IAAI,GAAG,MAAM,eAAe,UAAU;CACnD,MAAM,aAAa,mBAAmB,cAAc,WAAW;AAC/D,QAAO,cAAc,YAAY,KAAK,GAAG;AAC5C"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@towns-protocol/sdk-crypto",
3
+ "version": "0.0.244",
4
+ "packageManager": "yarn@3.8.0",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "main": "./dist/web/index.cjs",
10
+ "module": "./dist/web/index.js",
11
+ "types": "./dist/web/index.d.ts",
12
+ "sideEffects": false,
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/web/index.d.ts",
16
+ "node": "./dist/node/index.js",
17
+ "default": "./dist/web/index.js"
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "scripts": {
22
+ "build": "tsdown",
23
+ "cb": "yarn clean && yarn build",
24
+ "clean": "rm -rf dist",
25
+ "lint": "eslint --format unix ./src --max-warnings=0",
26
+ "lint:fix": "yarn lint --fix",
27
+ "test": "vitest",
28
+ "test:unit": "vitest run",
29
+ "watch": "tsdown --watch"
30
+ },
31
+ "dependencies": {
32
+ "@towns-protocol/dlog": "^0.0.244",
33
+ "@towns-protocol/encryption": "^0.0.244",
34
+ "@towns-protocol/proto": "^0.0.244"
35
+ },
36
+ "devDependencies": {
37
+ "@bufbuild/protobuf": "^2.2.2",
38
+ "@types/node": "^20.14.8",
39
+ "@typescript-eslint/eslint-plugin": "^8.29.0",
40
+ "@typescript-eslint/parser": "^8.29.0",
41
+ "eslint": "^8.57.1",
42
+ "eslint-import-resolver-typescript": "^4.3.2",
43
+ "eslint-plugin-import-x": "^4.10.2",
44
+ "eslint-plugin-tsdoc": "^0.3.0",
45
+ "happy-dom": "^15.11.7",
46
+ "tsdown": "^0.12.3",
47
+ "typescript": "^5.8.2",
48
+ "vitest": "^3.2.3"
49
+ },
50
+ "files": [
51
+ "/dist"
52
+ ],
53
+ "gitHead": "8f17f6f7a619532ed6e0e50687b9073d49cc8eb5"
54
+ }