@towns-protocol/sdk-crypto 0.0.348 → 0.0.349

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.
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require('../chunk-CUT6urMc.cjs');
2
- const __towns_protocol_dlog = require_chunk.__toESM(require("@towns-protocol/dlog"));
2
+ const __towns_protocol_utils = require_chunk.__toESM(require("@towns-protocol/utils"));
3
3
  const __towns_protocol_proto = require_chunk.__toESM(require("@towns-protocol/proto"));
4
4
  const __towns_protocol_encryption = require_chunk.__toESM(require("@towns-protocol/encryption"));
5
5
  const node_crypto = require_chunk.__toESM(require("node:crypto"));
@@ -74,7 +74,7 @@ async function decryptAESGCM(data, key, iv) {
74
74
  return new Uint8Array(decrypted.buffer, decrypted.byteOffset, decrypted.byteLength);
75
75
  }
76
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);
77
+ if (encryptedData.algorithm !== __towns_protocol_encryption.AES_GCM_DERIVED_ALGORITHM) (0, __towns_protocol_utils.throwWithCode)(`${encryptedData.algorithm}" algorithm not implemented`, __towns_protocol_proto.Err.UNIMPLEMENTED);
78
78
  const { key, iv } = await deriveKeyAndIV(keyPhrase);
79
79
  const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
80
80
  return decryptAESGCM(ciphertext, key, iv);
@@ -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/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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"}
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,4 +1,4 @@
1
- import { throwWithCode } from "@towns-protocol/dlog";
1
+ import { throwWithCode } from "@towns-protocol/utils";
2
2
  import { Err } from "@towns-protocol/proto";
3
3
  import { AES_GCM_DERIVED_ALGORITHM } from "@towns-protocol/encryption";
4
4
  import crypto from "node:crypto";
@@ -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/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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"}
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,5 +1,5 @@
1
1
  const require_chunk = require('../chunk-CUT6urMc.cjs');
2
- const __towns_protocol_dlog = require_chunk.__toESM(require("@towns-protocol/dlog"));
2
+ const __towns_protocol_utils = require_chunk.__toESM(require("@towns-protocol/utils"));
3
3
  const __towns_protocol_proto = require_chunk.__toESM(require("@towns-protocol/proto"));
4
4
  const __towns_protocol_encryption = require_chunk.__toESM(require("@towns-protocol/encryption"));
5
5
 
@@ -73,7 +73,7 @@ async function decryptAESGCM(data, key, iv) {
73
73
  return new Uint8Array(decryptedBuffer);
74
74
  }
75
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);
76
+ if (encryptedData.algorithm !== __towns_protocol_encryption.AES_GCM_DERIVED_ALGORITHM) (0, __towns_protocol_utils.throwWithCode)(`${encryptedData.algorithm}" algorithm not implemented`, __towns_protocol_proto.Err.UNIMPLEMENTED);
77
77
  const { key, iv } = await deriveKeyAndIV(keyPhrase);
78
78
  const ciphertext = base64ToUint8Array(encryptedData.ciphertext);
79
79
  return decryptAESGCM(ciphertext, key, iv);
@@ -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/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"}
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"}
package/dist/web/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { throwWithCode } from "@towns-protocol/dlog";
1
+ import { throwWithCode } from "@towns-protocol/utils";
2
2
  import { Err } from "@towns-protocol/proto";
3
3
  import { AES_GCM_DERIVED_ALGORITHM } from "@towns-protocol/encryption";
4
4
 
@@ -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/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"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@towns-protocol/sdk-crypto",
3
- "version": "0.0.348",
3
+ "version": "0.0.349",
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/dlog": "^0.0.348",
20
- "@towns-protocol/encryption": "^0.0.348",
21
- "@towns-protocol/proto": "^0.0.348"
19
+ "@towns-protocol/encryption": "^0.0.349",
20
+ "@towns-protocol/proto": "^0.0.349",
21
+ "@towns-protocol/utils": "^0.0.349"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@bufbuild/protobuf": "^2.2.2",
@@ -50,5 +50,5 @@
50
50
  "access": "public"
51
51
  },
52
52
  "sideEffects": false,
53
- "gitHead": "9d7daa617491dac9ea70b18ae5622b5ebb695119"
53
+ "gitHead": "203975e546c212816a5086c7c97a17c3f45b139f"
54
54
  }