{"version":3,"sources":["../src/node/aes-ctr.ts","../src/node/randomBytes.ts"],"sourcesContent":["import { arrayify } from '@ethersproject/bytes';\nimport { pbkdf2 } from '@ethersproject/pbkdf2';\nimport crypto from 'crypto';\n\nimport type { Keystore } from '../types';\n\nimport { randomBytes } from './randomBytes';\n\nconst ALGORITHM = 'aes-256-ctr';\n\nexport function bufferFromString(\n  string: string,\n  encoding: 'utf-8' | 'base64' = 'base64'\n): Uint8Array {\n  return Buffer.from(string, encoding);\n}\n\nexport function stringFromBuffer(\n  buffer: Uint8Array,\n  encoding: 'utf-8' | 'base64' = 'base64'\n): string {\n  return Buffer.from(buffer).toString(encoding);\n}\n\n/**\n * Generate a pbkdf2 key from a password and random salt\n */\nexport function keyFromPassword(password: string, saltBuffer: Uint8Array): Uint8Array {\n  const passBuffer = bufferFromString(String(password).normalize('NFKC'), 'utf-8');\n  const key = pbkdf2(passBuffer, saltBuffer, 100000, 32, 'sha256');\n\n  return arrayify(key);\n}\n\n/**\n * Encrypts a data object that can be any serializable value using\n * a provided password.\n *\n * @returns Promise<Keystore> object\n */\nexport async function encrypt<T>(password: string, data: T): Promise<Keystore> {\n  const iv = randomBytes(16);\n  const salt = randomBytes(32);\n  const secret = keyFromPassword(password, salt);\n  const dataBuffer = Uint8Array.from(Buffer.from(JSON.stringify(data), 'utf-8'));\n\n  const cipher = await crypto.createCipheriv(ALGORITHM, secret, iv);\n  let cipherData = cipher.update(dataBuffer);\n  cipherData = Buffer.concat([cipherData, cipher.final()]);\n\n  return {\n    data: stringFromBuffer(cipherData),\n    iv: stringFromBuffer(iv),\n    salt: stringFromBuffer(salt),\n  };\n}\n\n/**\n * Given a password and a keystore object, decrypts the text and returns\n * the resulting value\n */\nexport async function decrypt<T>(password: string, keystore: Keystore): Promise<T> {\n  const iv = bufferFromString(keystore.iv);\n  const salt = bufferFromString(keystore.salt);\n  const secret = keyFromPassword(password, salt);\n  const encryptedText = bufferFromString(keystore.data);\n\n  const decipher = await crypto.createDecipheriv(ALGORITHM, secret, iv);\n  const decrypted = decipher.update(encryptedText);\n  const deBuff = Buffer.concat([decrypted, decipher.final()]);\n  const decryptedData = Buffer.from(deBuff).toString('utf-8');\n\n  try {\n    return JSON.parse(decryptedData);\n  } catch {\n    throw new Error('Invalid credentials');\n  }\n}\n","import crypto from 'crypto';\n\nexport const randomBytes = (length: number) => {\n  const randomValues = crypto.randomBytes(length);\n  return randomValues;\n};\n"],"mappings":";AAAA,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB,OAAOA,aAAY;;;ACFnB,OAAO,YAAY;AAEZ,IAAM,cAAc,CAAC,WAAmB;AAC7C,QAAM,eAAe,OAAO,YAAY,MAAM;AAC9C,SAAO;AACT;;;ADGA,IAAM,YAAY;AAEX,SAAS,iBACd,QACA,WAA+B,UACnB;AACZ,SAAO,OAAO,KAAK,QAAQ,QAAQ;AACrC;AAEO,SAAS,iBACd,QACA,WAA+B,UACvB;AACR,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,QAAQ;AAC9C;AAKO,SAAS,gBAAgB,UAAkB,YAAoC;AACpF,QAAM,aAAa,iBAAiB,OAAO,QAAQ,EAAE,UAAU,MAAM,GAAG,OAAO;AAC/E,QAAM,MAAM,OAAO,YAAY,YAAY,KAAQ,IAAI,QAAQ;AAE/D,SAAO,SAAS,GAAG;AACrB;AAQA,eAAsB,QAAW,UAAkB,MAA4B;AAC7E,QAAM,KAAK,YAAY,EAAE;AACzB,QAAM,OAAO,YAAY,EAAE;AAC3B,QAAM,SAAS,gBAAgB,UAAU,IAAI;AAC7C,QAAM,aAAa,WAAW,KAAK,OAAO,KAAK,KAAK,UAAU,IAAI,GAAG,OAAO,CAAC;AAE7E,QAAM,SAAS,MAAMC,QAAO,eAAe,WAAW,QAAQ,EAAE;AAChE,MAAI,aAAa,OAAO,OAAO,UAAU;AACzC,eAAa,OAAO,OAAO,CAAC,YAAY,OAAO,MAAM,CAAC,CAAC;AAEvD,SAAO;AAAA,IACL,MAAM,iBAAiB,UAAU;AAAA,IACjC,IAAI,iBAAiB,EAAE;AAAA,IACvB,MAAM,iBAAiB,IAAI;AAAA,EAC7B;AACF;AAMA,eAAsB,QAAW,UAAkB,UAAgC;AACjF,QAAM,KAAK,iBAAiB,SAAS,EAAE;AACvC,QAAM,OAAO,iBAAiB,SAAS,IAAI;AAC3C,QAAM,SAAS,gBAAgB,UAAU,IAAI;AAC7C,QAAM,gBAAgB,iBAAiB,SAAS,IAAI;AAEpD,QAAM,WAAW,MAAMA,QAAO,iBAAiB,WAAW,QAAQ,EAAE;AACpE,QAAM,YAAY,SAAS,OAAO,aAAa;AAC/C,QAAM,SAAS,OAAO,OAAO,CAAC,WAAW,SAAS,MAAM,CAAC,CAAC;AAC1D,QAAM,gBAAgB,OAAO,KAAK,MAAM,EAAE,SAAS,OAAO;AAE1D,MAAI;AACF,WAAO,KAAK,MAAM,aAAa;AAAA,EACjC,QAAE;AACA,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACvC;AACF;","names":["crypto","crypto"]}