@towns-protocol/sdk-crypto 0.0.370 → 0.0.372
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/node/index.cjs +22 -0
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +8 -1
- package/dist/node/index.d.cts.map +1 -1
- package/dist/node/index.d.ts +8 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +22 -1
- package/dist/node/index.js.map +1 -1
- package/dist/web/index.cjs +22 -0
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.d.cts +8 -1
- package/dist/web/index.d.cts.map +1 -1
- package/dist/web/index.d.ts +8 -1
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +22 -1
- package/dist/web/index.js.map +1 -1
- package/package.json +5 -5
package/dist/node/index.cjs
CHANGED
|
@@ -79,6 +79,27 @@ async function decryptDerivedAESGCM(keyPhrase, encryptedData) {
|
|
|
79
79
|
const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
|
|
80
80
|
return decryptAESGCM(ciphertext, key, iv);
|
|
81
81
|
}
|
|
82
|
+
async function encryptChunkedAESGCM(data, chunkSize) {
|
|
83
|
+
if (!data || data.length === 0) throw new Error("Cannot encrypt undefined or empty data");
|
|
84
|
+
const secretKey = node_crypto.default.getRandomValues(new Uint8Array(32));
|
|
85
|
+
const maxPlaintextSize = chunkSize - 16;
|
|
86
|
+
const chunks = [];
|
|
87
|
+
let offset = 0;
|
|
88
|
+
while (offset < data.length) {
|
|
89
|
+
const dataChunk = data.slice(offset, offset + maxPlaintextSize);
|
|
90
|
+
const { ciphertext, iv } = await encryptAESGCM(dataChunk, secretKey);
|
|
91
|
+
if (ciphertext.byteLength > chunkSize) throw new Error(`Encrypted chunk exceeds chunkSize. Adjust chunkSize.`);
|
|
92
|
+
chunks.push({
|
|
93
|
+
ciphertext,
|
|
94
|
+
iv
|
|
95
|
+
});
|
|
96
|
+
offset += maxPlaintextSize;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
chunks,
|
|
100
|
+
secretKey
|
|
101
|
+
};
|
|
102
|
+
}
|
|
82
103
|
|
|
83
104
|
//#endregion
|
|
84
105
|
exports.base64ToUint8Array = base64ToUint8Array;
|
|
@@ -86,5 +107,6 @@ exports.decryptAESGCM = decryptAESGCM;
|
|
|
86
107
|
exports.decryptDerivedAESGCM = decryptDerivedAESGCM;
|
|
87
108
|
exports.deriveKeyAndIV = deriveKeyAndIV;
|
|
88
109
|
exports.encryptAESGCM = encryptAESGCM;
|
|
110
|
+
exports.encryptChunkedAESGCM = encryptChunkedAESGCM;
|
|
89
111
|
exports.uint8ArrayToBase64 = uint8ArrayToBase64;
|
|
90
112
|
//# sourceMappingURL=index.cjs.map
|
package/dist/node/index.cjs.map
CHANGED
|
@@ -1 +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/utils'\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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"}
|
|
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","chunkSize: number","chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }>"],"sources":["../../src/node/index.ts"],"sourcesContent":["import { throwWithCode } from '@towns-protocol/utils'\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\nexport async function encryptChunkedAESGCM(\n data: Uint8Array,\n chunkSize: number,\n): Promise<{\n chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }>\n secretKey: Uint8Array\n}> {\n if (!data || data.length === 0) {\n throw new Error('Cannot encrypt undefined or empty data')\n }\n const secretKey = crypto.getRandomValues(new Uint8Array(32))\n // Adjust chunk size to account for AES-GCM overhead (16-byte auth tag)\n const maxPlaintextSize = chunkSize - 16\n const chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }> = []\n\n let offset = 0\n while (offset < data.length) {\n const dataChunk = data.slice(offset, offset + maxPlaintextSize)\n const { ciphertext, iv } = await encryptAESGCM(dataChunk, secretKey)\n\n if (ciphertext.byteLength > chunkSize) {\n throw new Error(`Encrypted chunk exceeds chunkSize. Adjust chunkSize.`)\n }\n\n chunks.push({ ciphertext, iv })\n offset += maxPlaintextSize\n }\n\n return { chunks, secretKey }\n}\n"],"mappings":"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"}
|
package/dist/node/index.d.cts
CHANGED
|
@@ -14,8 +14,15 @@ declare function encryptAESGCM(data: Uint8Array, key?: Uint8Array, iv?: Uint8Arr
|
|
|
14
14
|
}>;
|
|
15
15
|
declare function decryptAESGCM(data: Uint8Array | string, key: Uint8Array, iv: Uint8Array): Promise<Uint8Array>;
|
|
16
16
|
declare function decryptDerivedAESGCM(keyPhrase: string, encryptedData: EncryptedData): Promise<Uint8Array>;
|
|
17
|
+
declare function encryptChunkedAESGCM(data: Uint8Array, chunkSize: number): Promise<{
|
|
18
|
+
chunks: Array<{
|
|
19
|
+
ciphertext: Uint8Array;
|
|
20
|
+
iv: Uint8Array;
|
|
21
|
+
}>;
|
|
22
|
+
secretKey: Uint8Array;
|
|
23
|
+
}>;
|
|
17
24
|
//# sourceMappingURL=index.d.ts.map
|
|
18
25
|
|
|
19
26
|
//#endregion
|
|
20
|
-
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
|
|
27
|
+
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, encryptChunkedAESGCM, uint8ArrayToBase64 };
|
|
21
28
|
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +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"}
|
|
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;AACzB,iBA0FY,oBAAA,CA1FZ,IAAA,EA2FA,UA3FA,EAAA,SAAA,EAAA,MAAA,CAAA,EA6FP,OA7FO,CAAA;EAAU,MACV,EA6FE,KA7FF,CAAA;IACD,UAAA,EA4FuB,UA5FvB;IACgB,EAAA,EA2FuB,UA3FvB;EAAU,CAAA,CAAA;EAAgB,SAAa,EA4FjD,UA5FiD;CAAU,CAAA;AAAhE"}
|
package/dist/node/index.d.ts
CHANGED
|
@@ -14,8 +14,15 @@ declare function encryptAESGCM(data: Uint8Array, key?: Uint8Array, iv?: Uint8Arr
|
|
|
14
14
|
}>;
|
|
15
15
|
declare function decryptAESGCM(data: Uint8Array | string, key: Uint8Array, iv: Uint8Array): Promise<Uint8Array>;
|
|
16
16
|
declare function decryptDerivedAESGCM(keyPhrase: string, encryptedData: EncryptedData): Promise<Uint8Array>;
|
|
17
|
+
declare function encryptChunkedAESGCM(data: Uint8Array, chunkSize: number): Promise<{
|
|
18
|
+
chunks: Array<{
|
|
19
|
+
ciphertext: Uint8Array;
|
|
20
|
+
iv: Uint8Array;
|
|
21
|
+
}>;
|
|
22
|
+
secretKey: Uint8Array;
|
|
23
|
+
}>;
|
|
17
24
|
//# sourceMappingURL=index.d.ts.map
|
|
18
25
|
|
|
19
26
|
//#endregion
|
|
20
|
-
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
|
|
27
|
+
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, encryptChunkedAESGCM, uint8ArrayToBase64 };
|
|
21
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/node/index.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
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;AACzB,iBA0FY,oBAAA,CA1FZ,IAAA,EA2FA,UA3FA,EAAA,SAAA,EAAA,MAAA,CAAA,EA6FP,OA7FO,CAAA;EAAU,MACV,EA6FE,KA7FF,CAAA;IACD,UAAA,EA4FuB,UA5FvB;IACgB,EAAA,EA2FuB,UA3FvB;EAAU,CAAA,CAAA;EAAgB,SAAa,EA4FjD,UA5FiD;CAAU,CAAA;AAAhE"}
|
package/dist/node/index.js
CHANGED
|
@@ -78,7 +78,28 @@ async function decryptDerivedAESGCM(keyPhrase, encryptedData) {
|
|
|
78
78
|
const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
|
|
79
79
|
return decryptAESGCM(ciphertext, key, iv);
|
|
80
80
|
}
|
|
81
|
+
async function encryptChunkedAESGCM(data, chunkSize) {
|
|
82
|
+
if (!data || data.length === 0) throw new Error("Cannot encrypt undefined or empty data");
|
|
83
|
+
const secretKey = crypto.getRandomValues(new Uint8Array(32));
|
|
84
|
+
const maxPlaintextSize = chunkSize - 16;
|
|
85
|
+
const chunks = [];
|
|
86
|
+
let offset = 0;
|
|
87
|
+
while (offset < data.length) {
|
|
88
|
+
const dataChunk = data.slice(offset, offset + maxPlaintextSize);
|
|
89
|
+
const { ciphertext, iv } = await encryptAESGCM(dataChunk, secretKey);
|
|
90
|
+
if (ciphertext.byteLength > chunkSize) throw new Error(`Encrypted chunk exceeds chunkSize. Adjust chunkSize.`);
|
|
91
|
+
chunks.push({
|
|
92
|
+
ciphertext,
|
|
93
|
+
iv
|
|
94
|
+
});
|
|
95
|
+
offset += maxPlaintextSize;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
chunks,
|
|
99
|
+
secretKey
|
|
100
|
+
};
|
|
101
|
+
}
|
|
81
102
|
|
|
82
103
|
//#endregion
|
|
83
|
-
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
|
|
104
|
+
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, encryptChunkedAESGCM, uint8ArrayToBase64 };
|
|
84
105
|
//# sourceMappingURL=index.js.map
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +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/utils'\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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"}
|
|
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","chunkSize: number","chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }>"],"sources":["../../src/node/index.ts"],"sourcesContent":["import { throwWithCode } from '@towns-protocol/utils'\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\nexport async function encryptChunkedAESGCM(\n data: Uint8Array,\n chunkSize: number,\n): Promise<{\n chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }>\n secretKey: Uint8Array\n}> {\n if (!data || data.length === 0) {\n throw new Error('Cannot encrypt undefined or empty data')\n }\n const secretKey = crypto.getRandomValues(new Uint8Array(32))\n // Adjust chunk size to account for AES-GCM overhead (16-byte auth tag)\n const maxPlaintextSize = chunkSize - 16\n const chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }> = []\n\n let offset = 0\n while (offset < data.length) {\n const dataChunk = data.slice(offset, offset + maxPlaintextSize)\n const { ciphertext, iv } = await encryptAESGCM(dataChunk, secretKey)\n\n if (ciphertext.byteLength > chunkSize) {\n throw new Error(`Encrypted chunk exceeds chunkSize. Adjust chunkSize.`)\n }\n\n chunks.push({ ciphertext, iv })\n offset += maxPlaintextSize\n }\n\n return { chunks, secretKey }\n}\n"],"mappings":"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"}
|
package/dist/web/index.cjs
CHANGED
|
@@ -78,6 +78,27 @@ async function decryptDerivedAESGCM(keyPhrase, encryptedData) {
|
|
|
78
78
|
const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
|
|
79
79
|
return decryptAESGCM(ciphertext, key, iv);
|
|
80
80
|
}
|
|
81
|
+
async function encryptChunkedAESGCM(data, chunkSize) {
|
|
82
|
+
if (!data || data.length === 0) throw new Error("Cannot encrypt undefined or empty data");
|
|
83
|
+
const secretKey = crypto.getRandomValues(new Uint8Array(32));
|
|
84
|
+
const maxPlaintextSize = chunkSize - 16;
|
|
85
|
+
const chunks = [];
|
|
86
|
+
let offset = 0;
|
|
87
|
+
while (offset < data.length) {
|
|
88
|
+
const dataChunk = data.slice(offset, offset + maxPlaintextSize);
|
|
89
|
+
const { ciphertext, iv } = await encryptAESGCM(dataChunk, secretKey);
|
|
90
|
+
if (ciphertext.byteLength > chunkSize) throw new Error(`Encrypted chunk exceeds chunkSize. Adjust chunkSize.`);
|
|
91
|
+
chunks.push({
|
|
92
|
+
ciphertext,
|
|
93
|
+
iv
|
|
94
|
+
});
|
|
95
|
+
offset += maxPlaintextSize;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
chunks,
|
|
99
|
+
secretKey
|
|
100
|
+
};
|
|
101
|
+
}
|
|
81
102
|
|
|
82
103
|
//#endregion
|
|
83
104
|
exports.base64ToUint8Array = base64ToUint8Array;
|
|
@@ -85,5 +106,6 @@ exports.decryptAESGCM = decryptAESGCM;
|
|
|
85
106
|
exports.decryptDerivedAESGCM = decryptDerivedAESGCM;
|
|
86
107
|
exports.deriveKeyAndIV = deriveKeyAndIV;
|
|
87
108
|
exports.encryptAESGCM = encryptAESGCM;
|
|
109
|
+
exports.encryptChunkedAESGCM = encryptChunkedAESGCM;
|
|
88
110
|
exports.uint8ArrayToBase64 = uint8ArrayToBase64;
|
|
89
111
|
//# sourceMappingURL=index.cjs.map
|
package/dist/web/index.cjs.map
CHANGED
|
@@ -1 +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/utils'\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,4CAAe,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"}
|
|
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","chunkSize: number","chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }>"],"sources":["../../src/web/index.ts"],"sourcesContent":["import { throwWithCode } from '@towns-protocol/utils'\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\nexport async function encryptChunkedAESGCM(\n data: Uint8Array,\n chunkSize: number,\n): Promise<{\n chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }>\n secretKey: Uint8Array\n}> {\n if (!data || data.length === 0) {\n throw new Error('Cannot encrypt undefined or empty data')\n }\n const secretKey = crypto.getRandomValues(new Uint8Array(32))\n // Adjust chunk size to account for AES-GCM overhead (16-byte auth tag)\n const maxPlaintextSize = chunkSize - 16\n const chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }> = []\n\n let offset = 0\n while (offset < data.length) {\n const dataChunk = data.slice(offset, offset + maxPlaintextSize)\n const { ciphertext, iv } = await encryptAESGCM(dataChunk, secretKey)\n\n if (ciphertext.byteLength > chunkSize) {\n throw new Error(`Encrypted chunk exceeds chunkSize. Adjust chunkSize.`)\n }\n\n chunks.push({ ciphertext, iv })\n offset += maxPlaintextSize\n }\n\n return { chunks, secretKey }\n}\n"],"mappings":"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"}
|
package/dist/web/index.d.cts
CHANGED
|
@@ -14,8 +14,15 @@ declare function encryptAESGCM(data: Uint8Array, key?: Uint8Array, iv?: Uint8Arr
|
|
|
14
14
|
}>;
|
|
15
15
|
declare function decryptAESGCM(data: Uint8Array | string, key: Uint8Array, iv: Uint8Array): Promise<Uint8Array>;
|
|
16
16
|
declare function decryptDerivedAESGCM(keyPhrase: string, encryptedData: EncryptedData): Promise<Uint8Array>;
|
|
17
|
+
declare function encryptChunkedAESGCM(data: Uint8Array, chunkSize: number): Promise<{
|
|
18
|
+
chunks: Array<{
|
|
19
|
+
ciphertext: Uint8Array;
|
|
20
|
+
iv: Uint8Array;
|
|
21
|
+
}>;
|
|
22
|
+
secretKey: Uint8Array;
|
|
23
|
+
}>;
|
|
17
24
|
//# sourceMappingURL=index.d.ts.map
|
|
18
25
|
|
|
19
26
|
//#endregion
|
|
20
|
-
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
|
|
27
|
+
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, encryptChunkedAESGCM, uint8ArrayToBase64 };
|
|
21
28
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/web/index.d.cts.map
CHANGED
|
@@ -1 +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"}
|
|
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;AACzB,iBAwFY,oBAAA,CAxFZ,IAAA,EAyFA,UAzFA,EAAA,SAAA,EAAA,MAAA,CAAA,EA2FP,OA3FO,CAAA;EAAU,MACV,EA2FE,KA3FF,CAAA;IACD,UAAA,EA0FuB,UA1FvB;IACgB,EAAA,EAyFuB,UAzFvB;EAAU,CAAA,CAAA;EAAgB,SAAa,EA0FjD,UA1FiD;CAAU,CAAA;AAAhE"}
|
package/dist/web/index.d.ts
CHANGED
|
@@ -14,8 +14,15 @@ declare function encryptAESGCM(data: Uint8Array, key?: Uint8Array, iv?: Uint8Arr
|
|
|
14
14
|
}>;
|
|
15
15
|
declare function decryptAESGCM(data: Uint8Array | string, key: Uint8Array, iv: Uint8Array): Promise<Uint8Array>;
|
|
16
16
|
declare function decryptDerivedAESGCM(keyPhrase: string, encryptedData: EncryptedData): Promise<Uint8Array>;
|
|
17
|
+
declare function encryptChunkedAESGCM(data: Uint8Array, chunkSize: number): Promise<{
|
|
18
|
+
chunks: Array<{
|
|
19
|
+
ciphertext: Uint8Array;
|
|
20
|
+
iv: Uint8Array;
|
|
21
|
+
}>;
|
|
22
|
+
secretKey: Uint8Array;
|
|
23
|
+
}>;
|
|
17
24
|
//# sourceMappingURL=index.d.ts.map
|
|
18
25
|
|
|
19
26
|
//#endregion
|
|
20
|
-
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
|
|
27
|
+
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, encryptChunkedAESGCM, uint8ArrayToBase64 };
|
|
21
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/web/index.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
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;AACzB,iBAwFY,oBAAA,CAxFZ,IAAA,EAyFA,UAzFA,EAAA,SAAA,EAAA,MAAA,CAAA,EA2FP,OA3FO,CAAA;EAAU,MACV,EA2FE,KA3FF,CAAA;IACD,UAAA,EA0FuB,UA1FvB;IACgB,EAAA,EAyFuB,UAzFvB;EAAU,CAAA,CAAA;EAAgB,SAAa,EA0FjD,UA1FiD;CAAU,CAAA;AAAhE"}
|
package/dist/web/index.js
CHANGED
|
@@ -77,7 +77,28 @@ async function decryptDerivedAESGCM(keyPhrase, encryptedData) {
|
|
|
77
77
|
const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
|
|
78
78
|
return decryptAESGCM(ciphertext, key, iv);
|
|
79
79
|
}
|
|
80
|
+
async function encryptChunkedAESGCM(data, chunkSize) {
|
|
81
|
+
if (!data || data.length === 0) throw new Error("Cannot encrypt undefined or empty data");
|
|
82
|
+
const secretKey = crypto.getRandomValues(new Uint8Array(32));
|
|
83
|
+
const maxPlaintextSize = chunkSize - 16;
|
|
84
|
+
const chunks = [];
|
|
85
|
+
let offset = 0;
|
|
86
|
+
while (offset < data.length) {
|
|
87
|
+
const dataChunk = data.slice(offset, offset + maxPlaintextSize);
|
|
88
|
+
const { ciphertext, iv } = await encryptAESGCM(dataChunk, secretKey);
|
|
89
|
+
if (ciphertext.byteLength > chunkSize) throw new Error(`Encrypted chunk exceeds chunkSize. Adjust chunkSize.`);
|
|
90
|
+
chunks.push({
|
|
91
|
+
ciphertext,
|
|
92
|
+
iv
|
|
93
|
+
});
|
|
94
|
+
offset += maxPlaintextSize;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
chunks,
|
|
98
|
+
secretKey
|
|
99
|
+
};
|
|
100
|
+
}
|
|
80
101
|
|
|
81
102
|
//#endregion
|
|
82
|
-
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, uint8ArrayToBase64 };
|
|
103
|
+
export { base64ToUint8Array, decryptAESGCM, decryptDerivedAESGCM, deriveKeyAndIV, encryptAESGCM, encryptChunkedAESGCM, uint8ArrayToBase64 };
|
|
83
104
|
//# sourceMappingURL=index.js.map
|
package/dist/web/index.js.map
CHANGED
|
@@ -1 +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/utils'\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"}
|
|
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","chunkSize: number","chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }>"],"sources":["../../src/web/index.ts"],"sourcesContent":["import { throwWithCode } from '@towns-protocol/utils'\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\nexport async function encryptChunkedAESGCM(\n data: Uint8Array,\n chunkSize: number,\n): Promise<{\n chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }>\n secretKey: Uint8Array\n}> {\n if (!data || data.length === 0) {\n throw new Error('Cannot encrypt undefined or empty data')\n }\n const secretKey = crypto.getRandomValues(new Uint8Array(32))\n // Adjust chunk size to account for AES-GCM overhead (16-byte auth tag)\n const maxPlaintextSize = chunkSize - 16\n const chunks: Array<{ ciphertext: Uint8Array; iv: Uint8Array }> = []\n\n let offset = 0\n while (offset < data.length) {\n const dataChunk = data.slice(offset, offset + maxPlaintextSize)\n const { ciphertext, iv } = await encryptAESGCM(dataChunk, secretKey)\n\n if (ciphertext.byteLength > chunkSize) {\n throw new Error(`Encrypted chunk exceeds chunkSize. Adjust chunkSize.`)\n }\n\n chunks.push({ ciphertext, iv })\n offset += maxPlaintextSize\n }\n\n return { chunks, secretKey }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@towns-protocol/sdk-crypto",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.372",
|
|
4
4
|
"packageManager": "yarn@3.8.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/web/index.cjs",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"watch": "tsdown --watch"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@towns-protocol/encryption": "^0.0.
|
|
20
|
-
"@towns-protocol/proto": "^0.0.
|
|
21
|
-
"@towns-protocol/utils": "^0.0.
|
|
19
|
+
"@towns-protocol/encryption": "^0.0.372",
|
|
20
|
+
"@towns-protocol/proto": "^0.0.372",
|
|
21
|
+
"@towns-protocol/utils": "^0.0.372"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@bufbuild/protobuf": "^2.9.0",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"sideEffects": false,
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "064d93eb0334ff96e7781dc951e99f41accca3c2"
|
|
54
54
|
}
|