"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ivLength = void 0;
exports.decrypt = decrypt;
exports.encrypt = encrypt;
exports.getKey = getKey;
exports.randomSalt = randomSalt;
const Bytes = require("./Bytes.js");
const Hex = require("./Hex.js");
exports.ivLength = 16;
async function decrypt(value, key, options = {}) {
    const { as = typeof value === 'string' ? 'Hex' : 'Bytes' } = options;
    const encrypted = Bytes.from(value);
    const iv = encrypted.slice(0, exports.ivLength);
    const data = encrypted.slice(exports.ivLength);
    const decrypted = await globalThis.crypto.subtle.decrypt({
        name: 'AES-GCM',
        iv,
    }, key, Bytes.from(data));
    const result = new Uint8Array(decrypted);
    if (as === 'Bytes')
        return result;
    return Hex.from(result);
}
async function encrypt(value, key, options = {}) {
    const { as = typeof value === 'string' ? 'Hex' : 'Bytes' } = options;
    const iv = Bytes.random(exports.ivLength);
    const encrypted = await globalThis.crypto.subtle.encrypt({
        name: 'AES-GCM',
        iv,
    }, key, Bytes.from(value));
    const result = Bytes.concat(iv, new Uint8Array(encrypted));
    if (as === 'Bytes')
        return result;
    return Hex.from(result);
}
async function getKey(options) {
    const { iterations = 900_000, password, salt = randomSalt(32) } = options;
    const baseKey = await globalThis.crypto.subtle.importKey('raw', Bytes.fromString(password), { name: 'PBKDF2' }, false, ['deriveBits', 'deriveKey']);
    const key = await globalThis.crypto.subtle.deriveKey({
        name: 'PBKDF2',
        salt,
        iterations,
        hash: 'SHA-256',
    }, baseKey, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
    return key;
}
function randomSalt(size = 32) {
    return Bytes.random(size);
}
//# sourceMappingURL=AesGcm.js.map