(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('crypto-js'), require('@iotize/common/byte-converter'), require('@iotize/common/byte-stream'), require('@iotize/common/crypto')) :
    typeof define === 'function' && define.amd ? define('@iotize/tap/crypto', ['exports', 'crypto-js', '@iotize/common/byte-converter', '@iotize/common/byte-stream', '@iotize/common/crypto'], factory) :
    (global = global || self, factory((global.iotize = global.iotize || {}, global.iotize.tap = global.iotize.tap || {}, global.iotize.tap.crypto = {}), global.cryptoJs, global.byteConverter, global.byteStream, global.crypto));
}(this, (function (exports, cryptoJs, byteConverter, byteStream, crypto) { 'use strict';

    var __read = (this && this.__read) || function (o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) m.call(i);
            }
            finally { if (e) throw e.error; }
        }
        return ar;
    };
    var __spread = (this && this.__spread) || function () {
        for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
        return ar;
    };
    var CryptoHelper = /** @class */ (function () {
        function CryptoHelper() {
        }
        CryptoHelper.sanitizeInput = function (input) {
            if (input instanceof Uint8Array) {
                return CryptoHelper.byteArrayToWordArray(input);
            }
            else {
                return input;
            }
        };
        CryptoHelper.byteArrayToWordArray = function (ba) {
            var wa = [];
            for (var i = 0; i < ba.length; i++) {
                wa[(i / 4) | 0] |= ba[i] << (24 - 8 * i);
            }
            var result = cryptoJs.lib.WordArray.create(wa);
            result.sigBytes = ba.length;
            return result;
        };
        CryptoHelper.getAlgoImpl = function (type) {
            switch (type) {
                case 'sha1':
                    return cryptoJs.algo.SHA1;
                case 'sha256':
                    return cryptoJs.algo.SHA256;
                default:
                    throw new Error('Unknown algo type: ' + type);
            }
        };
        CryptoHelper.wordToByteArray = function (word, length) {
            var ba = [];
            if (length > 0)
                ba.push(word >>> 24);
            if (length > 1)
                ba.push((word >>> 16) & 0xff);
            if (length > 2)
                ba.push((word >>> 8) & 0xff);
            if (length > 3)
                ba.push(word & 0xff);
            return Uint8Array.from(ba);
        };
        CryptoHelper.libWordArrayToByteArray = function (libWordArray, length) {
            if (!length) {
                length = libWordArray.sigBytes;
            }
            var wordArray = libWordArray.words;
            var result = [];
            var i = 0;
            while (length > 0) {
                var bytes = CryptoHelper.wordToByteArray(wordArray[i], Math.min(4, length));
                length -= bytes.length;
                result.push(bytes);
                i++;
            }
            return byteStream.KaitaiStreamWriter.mergeArrays.apply(byteStream.KaitaiStreamWriter, __spread(result));
        };
        CryptoHelper.wordArrayToByteArray = function (input) {
            return byteConverter.hexStringToBuffer(input.toString(cryptoJs.enc.Hex));
        };
        return CryptoHelper;
    }());

    function hmacSHA256(data, key) {
        var wordArray = CryptoHelper.sanitizeInput(data);
        var keyArray = CryptoHelper.sanitizeInput(key);
        var result = cryptoJs.HmacSHA256(wordArray, keyArray);
        return CryptoHelper.wordArrayToByteArray(result);
    }

    /**
     * PBKDF2 function (pssword-based key derivation function)
     * @param input
     * @param salt
     * @iterations
     * @param keySize number of 32 bit words
     */
    function pbkdf2(input, salt, iterations, keySize) {
        var wordInput = CryptoHelper.sanitizeInput(input);
        var wordSalt = CryptoHelper.sanitizeInput(salt);
        var options = {
            iterations: iterations,
            keySize: keySize,
            hasher: cryptoJs.algo.SHA256
        };
        if (options.keySize === undefined) {
            delete options.keySize;
        }
        var hash = cryptoJs.PBKDF2(wordInput, wordSalt, options);
        return CryptoHelper.wordArrayToByteArray(hash);
    }

    var ALGO_TYPE = 'sha1';
    var ITERATION_NUMBER = 4096;
    var KEY_SIZE = 128;
    var DEFAULT_SALT = 'n0 salt in 1oTi2e'; // TODO read from iotize ...
    var passwordHasher = new crypto.ShaHasher({
        type: ALGO_TYPE,
        iterations: ITERATION_NUMBER,
        salt: DEFAULT_SALT,
        keySize: KEY_SIZE
    });

    exports.hmacSHA256 = hmacSHA256;
    exports.passwordHasher = passwordHasher;
    exports.pbkdf2 = pbkdf2;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=iotize-tap-crypto.umd.js.map
