UNPKG

@digitalpersona/websdk

Version:

HID DigitalPersona WebSDK library

1,592 lines (1,404 loc) 200 kB
/*! * async * https://github.com/caolan/async * * Copyright 2010-2014 Caolan McMahon * Released under the MIT license */ ;(function () { var async = {}; function noop() {} function identity(v) { return v; } function toBool(v) { return !!v; } function notId(v) { return !v; } // global on the server, window in the browser var previous_async; // Establish the root object, `window` (`self`) in the browser, `global` // on the server, or `this` in some virtual machines. We use `self` // instead of `window` for `WebWorker` support. var root = typeof self === 'object' && self.self === self && self || typeof global === 'object' && global.global === global && global || this; if (root != null) { previous_async = root.async; } async.noConflict = function () { root.async = previous_async; return async; }; function only_once(fn) { return function() { if (fn === null) throw new Error("Callback was already called."); fn.apply(this, arguments); fn = null; }; } function _once(fn) { return function() { if (fn === null) return; fn.apply(this, arguments); fn = null; }; } //// cross-browser compatiblity functions //// var _toString = Object.prototype.toString; var _isArray = Array.isArray || function (obj) { return _toString.call(obj) === '[object Array]'; }; // Ported from underscore.js isObject var _isObject = function(obj) { var type = typeof obj; return type === 'function' || type === 'object' && !!obj; }; function _isArrayLike(arr) { return _isArray(arr) || ( // has a positive integer length property typeof arr.length === "number" && arr.length >= 0 && arr.length % 1 === 0 ); } function _arrayEach(arr, iterator) { var index = -1, length = arr.length; while (++index < length) { iterator(arr[index], index, arr); } } function _map(arr, iterator) { var index = -1, length = arr.length, result = Array(length); while (++index < length) { result[index] = iterator(arr[index], index, arr); } return result; } function _range(count) { return _map(Array(count), function (v, i) { return i; }); } function _reduce(arr, iterator, memo) { _arrayEach(arr, function (x, i, a) { memo = iterator(memo, x, i, a); }); return memo; } function _forEachOf(object, iterator) { _arrayEach(_keys(object), function (key) { iterator(object[key], key); }); } function _indexOf(arr, item) { for (var i = 0; i < arr.length; i++) { if (arr[i] === item) return i; } return -1; } var _keys = Object.keys || function (obj) { var keys = []; for (var k in obj) { if (obj.hasOwnProperty(k)) { keys.push(k); } } return keys; }; function _keyIterator(coll) { var i = -1; var len; var keys; if (_isArrayLike(coll)) { len = coll.length; return function next() { i++; return i < len ? i : null; }; } else { keys = _keys(coll); len = keys.length; return function next() { i++; return i < len ? keys[i] : null; }; } } // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html) // This accumulates the arguments passed into an array, after a given index. // From underscore.js (https://github.com/jashkenas/underscore/pull/2140). function _restParam(func, startIndex) { startIndex = startIndex == null ? func.length - 1 : +startIndex; return function() { var length = Math.max(arguments.length - startIndex, 0); var rest = Array(length); for (var index = 0; index < length; index++) { rest[index] = arguments[index + startIndex]; } switch (startIndex) { case 0: return func.call(this, rest); case 1: return func.call(this, arguments[0], rest); } // Currently unused but handle cases outside of the switch statement: // var args = Array(startIndex + 1); // for (index = 0; index < startIndex; index++) { // args[index] = arguments[index]; // } // args[startIndex] = rest; // return func.apply(this, args); }; } function _withoutIndex(iterator) { return function (value, index, callback) { return iterator(value, callback); }; } //// exported async module functions //// //// nextTick implementation with browser-compatible fallback //// // capture the global reference to guard against fakeTimer mocks var _setImmediate = typeof setImmediate === 'function' && setImmediate; var _delay = _setImmediate ? function(fn) { // not a direct alias for IE10 compatibility _setImmediate(fn); } : function(fn) { setTimeout(function() { fn(); }, 0); }; if (typeof process === 'object' && typeof process.nextTick === 'function') { async.nextTick = process.nextTick; } else { async.nextTick = _delay; } async.setImmediate = _setImmediate ? _delay : async.nextTick; async.forEach = async.each = function (arr, iterator, callback) { return async.eachOf(arr, _withoutIndex(iterator), callback); }; async.forEachSeries = async.eachSeries = function (arr, iterator, callback) { return async.eachOfSeries(arr, _withoutIndex(iterator), callback); }; async.forEachLimit = async.eachLimit = function (arr, limit, iterator, callback) { return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback); }; async.forEachOf = async.eachOf = function (object, iterator, callback) { callback = _once(callback || noop); object = object || []; var iter = _keyIterator(object); var key, completed = 0; while ((key = iter()) != null) { completed += 1; iterator(object[key], key, only_once(done)); } if (completed === 0) callback(null); function done(err) { completed--; if (err) { callback(err); } // Check key is null in case iterator isn't exhausted // and done resolved synchronously. else if (key === null && completed <= 0) { callback(null); } } }; async.forEachOfSeries = async.eachOfSeries = function (obj, iterator, callback) { callback = _once(callback || noop); obj = obj || []; var nextKey = _keyIterator(obj); var key = nextKey(); function iterate() { var sync = true; if (key === null) { return callback(null); } iterator(obj[key], key, only_once(function (err) { if (err) { callback(err); } else { key = nextKey(); if (key === null) { return callback(null); } else { if (sync) { async.setImmediate(iterate); } else { iterate(); } } } })); sync = false; } iterate(); }; async.forEachOfLimit = async.eachOfLimit = function (obj, limit, iterator, callback) { _eachOfLimit(limit)(obj, iterator, callback); }; function _eachOfLimit(limit) { return function (obj, iterator, callback) { callback = _once(callback || noop); obj = obj || []; var nextKey = _keyIterator(obj); if (limit <= 0) { return callback(null); } var done = false; var running = 0; var errored = false; (function replenish () { if (done && running <= 0) { return callback(null); } while (running < limit && !errored) { var key = nextKey(); if (key === null) { done = true; if (running <= 0) { callback(null); } return; } running += 1; iterator(obj[key], key, only_once(function (err) { running -= 1; if (err) { callback(err); errored = true; } else { replenish(); } })); } })(); }; } function doParallel(fn) { return function (obj, iterator, callback) { return fn(async.eachOf, obj, iterator, callback); }; } function doParallelLimit(fn) { return function (obj, limit, iterator, callback) { return fn(_eachOfLimit(limit), obj, iterator, callback); }; } function doSeries(fn) { return function (obj, iterator, callback) { return fn(async.eachOfSeries, obj, iterator, callback); }; } function _asyncMap(eachfn, arr, iterator, callback) { callback = _once(callback || noop); arr = arr || []; var results = _isArrayLike(arr) ? [] : {}; eachfn(arr, function (value, index, callback) { iterator(value, function (err, v) { results[index] = v; callback(err); }); }, function (err) { callback(err, results); }); } async.map = doParallel(_asyncMap); async.mapSeries = doSeries(_asyncMap); async.mapLimit = doParallelLimit(_asyncMap); // reduce only has a series version, as doing reduce in parallel won't // work in many situations. async.inject = async.foldl = async.reduce = function (arr, memo, iterator, callback) { async.eachOfSeries(arr, function (x, i, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { callback(err, memo); }); }; async.foldr = async.reduceRight = function (arr, memo, iterator, callback) { var reversed = _map(arr, identity).reverse(); async.reduce(reversed, memo, iterator, callback); }; async.transform = function (arr, memo, iterator, callback) { if (arguments.length === 3) { callback = iterator; iterator = memo; memo = _isArray(arr) ? [] : {}; } async.eachOf(arr, function(v, k, cb) { iterator(memo, v, k, cb); }, function(err) { callback(err, memo); }); }; function _filter(eachfn, arr, iterator, callback) { var results = []; eachfn(arr, function (x, index, callback) { iterator(x, function (v) { if (v) { results.push({index: index, value: x}); } callback(); }); }, function () { callback(_map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); } async.select = async.filter = doParallel(_filter); async.selectLimit = async.filterLimit = doParallelLimit(_filter); async.selectSeries = async.filterSeries = doSeries(_filter); function _reject(eachfn, arr, iterator, callback) { _filter(eachfn, arr, function(value, cb) { iterator(value, function(v) { cb(!v); }); }, callback); } async.reject = doParallel(_reject); async.rejectLimit = doParallelLimit(_reject); async.rejectSeries = doSeries(_reject); function _createTester(eachfn, check, getResult) { return function(arr, limit, iterator, cb) { function done() { if (cb) cb(getResult(false, void 0)); } function iteratee(x, _, callback) { if (!cb) return callback(); iterator(x, function (v) { if (cb && check(v)) { cb(getResult(true, x)); cb = iterator = false; } callback(); }); } if (arguments.length > 3) { eachfn(arr, limit, iteratee, done); } else { cb = iterator; iterator = limit; eachfn(arr, iteratee, done); } }; } async.any = async.some = _createTester(async.eachOf, toBool, identity); async.someLimit = _createTester(async.eachOfLimit, toBool, identity); async.all = async.every = _createTester(async.eachOf, notId, notId); async.everyLimit = _createTester(async.eachOfLimit, notId, notId); function _findGetResult(v, x) { return x; } async.detect = _createTester(async.eachOf, identity, _findGetResult); async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult); async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult); async.sortBy = function (arr, iterator, callback) { async.map(arr, function (x, callback) { iterator(x, function (err, criteria) { if (err) { callback(err); } else { callback(null, {value: x, criteria: criteria}); } }); }, function (err, results) { if (err) { return callback(err); } else { callback(null, _map(results.sort(comparator), function (x) { return x.value; })); } }); function comparator(left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; } }; async.auto = function (tasks, concurrency, callback) { if (!callback) { // concurrency is optional, shift the args. callback = concurrency; concurrency = null; } callback = _once(callback || noop); var keys = _keys(tasks); var remainingTasks = keys.length; if (!remainingTasks) { return callback(null); } if (!concurrency) { concurrency = remainingTasks; } var results = {}; var runningTasks = 0; var listeners = []; function addListener(fn) { listeners.unshift(fn); } function removeListener(fn) { var idx = _indexOf(listeners, fn); if (idx >= 0) listeners.splice(idx, 1); } function taskComplete() { remainingTasks--; _arrayEach(listeners.slice(0), function (fn) { fn(); }); } addListener(function () { if (!remainingTasks) { callback(null, results); } }); _arrayEach(keys, function (k) { var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; var taskCallback = _restParam(function(err, args) { runningTasks--; if (args.length <= 1) { args = args[0]; } if (err) { var safeResults = {}; _forEachOf(results, function(val, rkey) { safeResults[rkey] = val; }); safeResults[k] = args; callback(err, safeResults); } else { results[k] = args; async.setImmediate(taskComplete); } }); var requires = task.slice(0, task.length - 1); // prevent dead-locks var len = requires.length; var dep; while (len--) { if (!(dep = tasks[requires[len]])) { throw new Error('Has inexistant dependency'); } if (_isArray(dep) && _indexOf(dep, k) >= 0) { throw new Error('Has cyclic dependencies'); } } function ready() { return runningTasks < concurrency && _reduce(requires, function (a, x) { return (a && results.hasOwnProperty(x)); }, true) && !results.hasOwnProperty(k); } if (ready()) { runningTasks++; task[task.length - 1](taskCallback, results); } else { addListener(listener); } function listener() { if (ready()) { runningTasks++; removeListener(listener); task[task.length - 1](taskCallback, results); } } }); }; async.retry = function(times, task, callback) { var DEFAULT_TIMES = 5; var DEFAULT_INTERVAL = 0; var attempts = []; var opts = { times: DEFAULT_TIMES, interval: DEFAULT_INTERVAL }; function parseTimes(acc, t){ if(typeof t === 'number'){ acc.times = parseInt(t, 10) || DEFAULT_TIMES; } else if(typeof t === 'object'){ acc.times = parseInt(t.times, 10) || DEFAULT_TIMES; acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL; } else { throw new Error('Unsupported argument type for \'times\': ' + typeof t); } } var length = arguments.length; if (length < 1 || length > 3) { throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)'); } else if (length <= 2 && typeof times === 'function') { callback = task; task = times; } if (typeof times !== 'function') { parseTimes(opts, times); } opts.callback = callback; opts.task = task; function wrappedTask(wrappedCallback, wrappedResults) { function retryAttempt(task, finalAttempt) { return function(seriesCallback) { task(function(err, result){ seriesCallback(!err || finalAttempt, {err: err, result: result}); }, wrappedResults); }; } function retryInterval(interval){ return function(seriesCallback){ setTimeout(function(){ seriesCallback(null); }, interval); }; } while (opts.times) { var finalAttempt = !(opts.times-=1); attempts.push(retryAttempt(opts.task, finalAttempt)); if(!finalAttempt && opts.interval > 0){ attempts.push(retryInterval(opts.interval)); } } async.series(attempts, function(done, data){ data = data[data.length - 1]; (wrappedCallback || opts.callback)(data.err, data.result); }); } // If a callback is passed, run this as a controll flow return opts.callback ? wrappedTask() : wrappedTask; }; async.waterfall = function (tasks, callback) { callback = _once(callback || noop); if (!_isArray(tasks)) { var err = new Error('First argument to waterfall must be an array of functions'); return callback(err); } if (!tasks.length) { return callback(); } function wrapIterator(iterator) { return _restParam(function (err, args) { if (err) { callback.apply(null, [err].concat(args)); } else { var next = iterator.next(); if (next) { args.push(wrapIterator(next)); } else { args.push(callback); } ensureAsync(iterator).apply(null, args); } }); } wrapIterator(async.iterator(tasks))(); }; function _parallel(eachfn, tasks, callback) { callback = callback || noop; var results = _isArrayLike(tasks) ? [] : {}; eachfn(tasks, function (task, key, callback) { task(_restParam(function (err, args) { if (args.length <= 1) { args = args[0]; } results[key] = args; callback(err); })); }, function (err) { callback(err, results); }); } async.parallel = function (tasks, callback) { _parallel(async.eachOf, tasks, callback); }; async.parallelLimit = function(tasks, limit, callback) { _parallel(_eachOfLimit(limit), tasks, callback); }; async.series = function(tasks, callback) { _parallel(async.eachOfSeries, tasks, callback); }; async.iterator = function (tasks) { function makeCallback(index) { function fn() { if (tasks.length) { tasks[index].apply(null, arguments); } return fn.next(); } fn.next = function () { return (index < tasks.length - 1) ? makeCallback(index + 1): null; }; return fn; } return makeCallback(0); }; async.apply = _restParam(function (fn, args) { return _restParam(function (callArgs) { return fn.apply( null, args.concat(callArgs) ); }); }); function _concat(eachfn, arr, fn, callback) { var result = []; eachfn(arr, function (x, index, cb) { fn(x, function (err, y) { result = result.concat(y || []); cb(err); }); }, function (err) { callback(err, result); }); } async.concat = doParallel(_concat); async.concatSeries = doSeries(_concat); async.whilst = function (test, iterator, callback) { callback = callback || noop; if (test()) { var next = _restParam(function(err, args) { if (err) { callback(err); } else if (test.apply(this, args)) { iterator(next); } else { callback(null); } }); iterator(next); } else { callback(null); } }; async.doWhilst = function (iterator, test, callback) { var calls = 0; return async.whilst(function() { return ++calls <= 1 || test.apply(this, arguments); }, iterator, callback); }; async.until = function (test, iterator, callback) { return async.whilst(function() { return !test.apply(this, arguments); }, iterator, callback); }; async.doUntil = function (iterator, test, callback) { return async.doWhilst(iterator, function() { return !test.apply(this, arguments); }, callback); }; async.during = function (test, iterator, callback) { callback = callback || noop; var next = _restParam(function(err, args) { if (err) { callback(err); } else { args.push(check); test.apply(this, args); } }); var check = function(err, truth) { if (err) { callback(err); } else if (truth) { iterator(next); } else { callback(null); } }; test(check); }; async.doDuring = function (iterator, test, callback) { var calls = 0; async.during(function(next) { if (calls++ < 1) { next(null, true); } else { test.apply(this, arguments); } }, iterator, callback); }; function _queue(worker, concurrency, payload) { if (concurrency == null) { concurrency = 1; } else if(concurrency === 0) { throw new Error('Concurrency must not be zero'); } function _insert(q, data, pos, callback) { if (callback != null && typeof callback !== "function") { throw new Error("task callback must be a function"); } q.started = true; if (!_isArray(data)) { data = [data]; } if(data.length === 0 && q.idle()) { // call drain immediately if there are no tasks return async.setImmediate(function() { q.drain(); }); } _arrayEach(data, function(task) { var item = { data: task, callback: callback || noop }; if (pos) { q.tasks.unshift(item); } else { q.tasks.push(item); } if (q.tasks.length === q.concurrency) { q.saturated(); } }); async.setImmediate(q.process); } function _next(q, tasks) { return function(){ workers -= 1; var removed = false; var args = arguments; _arrayEach(tasks, function (task) { _arrayEach(workersList, function (worker, index) { if (worker === task && !removed) { workersList.splice(index, 1); removed = true; } }); task.callback.apply(task, args); }); if (q.tasks.length + workers === 0) { q.drain(); } q.process(); }; } var workers = 0; var workersList = []; var q = { tasks: [], concurrency: concurrency, payload: payload, saturated: noop, empty: noop, drain: noop, started: false, paused: false, push: function (data, callback) { _insert(q, data, false, callback); }, kill: function () { q.drain = noop; q.tasks = []; }, unshift: function (data, callback) { _insert(q, data, true, callback); }, process: function () { if (!q.paused && workers < q.concurrency && q.tasks.length) { while(workers < q.concurrency && q.tasks.length){ var tasks = q.payload ? q.tasks.splice(0, q.payload) : q.tasks.splice(0, q.tasks.length); var data = _map(tasks, function (task) { return task.data; }); if (q.tasks.length === 0) { q.empty(); } workers += 1; workersList.push(tasks[0]); var cb = only_once(_next(q, tasks)); worker(data, cb); } } }, length: function () { return q.tasks.length; }, running: function () { return workers; }, workersList: function () { return workersList; }, idle: function() { return q.tasks.length + workers === 0; }, pause: function () { q.paused = true; }, resume: function () { if (q.paused === false) { return; } q.paused = false; var resumeCount = Math.min(q.concurrency, q.tasks.length); // Need to call q.process once per concurrent // worker to preserve full concurrency after pause for (var w = 1; w <= resumeCount; w++) { async.setImmediate(q.process); } } }; return q; } async.queue = function (worker, concurrency) { var q = _queue(function (items, cb) { worker(items[0], cb); }, concurrency, 1); return q; }; async.priorityQueue = function (worker, concurrency) { function _compareTasks(a, b){ return a.priority - b.priority; } function _binarySearch(sequence, item, compare) { var beg = -1, end = sequence.length - 1; while (beg < end) { var mid = beg + ((end - beg + 1) >>> 1); if (compare(item, sequence[mid]) >= 0) { beg = mid; } else { end = mid - 1; } } return beg; } function _insert(q, data, priority, callback) { if (callback != null && typeof callback !== "function") { throw new Error("task callback must be a function"); } q.started = true; if (!_isArray(data)) { data = [data]; } if(data.length === 0) { // call drain immediately if there are no tasks return async.setImmediate(function() { q.drain(); }); } _arrayEach(data, function(task) { var item = { data: task, priority: priority, callback: typeof callback === 'function' ? callback : noop }; q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); if (q.tasks.length === q.concurrency) { q.saturated(); } async.setImmediate(q.process); }); } // Start with a normal queue var q = async.queue(worker, concurrency); // Override push to accept second parameter representing priority q.push = function (data, priority, callback) { _insert(q, data, priority, callback); }; // Remove unshift function delete q.unshift; return q; }; async.cargo = function (worker, payload) { return _queue(worker, 1, payload); }; function _console_fn(name) { return _restParam(function (fn, args) { fn.apply(null, args.concat([_restParam(function (err, args) { if (typeof console === 'object') { if (err) { if (console.error) { console.error(err); } } else if (console[name]) { _arrayEach(args, function (x) { console[name](x); }); } } })])); }); } async.log = _console_fn('log'); async.dir = _console_fn('dir'); /*async.info = _console_fn('info'); async.warn = _console_fn('warn'); async.error = _console_fn('error');*/ async.memoize = function (fn, hasher) { var memo = {}; var queues = {}; hasher = hasher || identity; var memoized = _restParam(function memoized(args) { var callback = args.pop(); var key = hasher.apply(null, args); if (key in memo) { async.setImmediate(function () { callback.apply(null, memo[key]); }); } else if (key in queues) { queues[key].push(callback); } else { queues[key] = [callback]; fn.apply(null, args.concat([_restParam(function (args) { memo[key] = args; var q = queues[key]; delete queues[key]; for (var i = 0, l = q.length; i < l; i++) { q[i].apply(null, args); } })])); } }); memoized.memo = memo; memoized.unmemoized = fn; return memoized; }; async.unmemoize = function (fn) { return function () { return (fn.unmemoized || fn).apply(null, arguments); }; }; function _times(mapper) { return function (count, iterator, callback) { mapper(_range(count), iterator, callback); }; } async.times = _times(async.map); async.timesSeries = _times(async.mapSeries); async.timesLimit = function (count, limit, iterator, callback) { return async.mapLimit(_range(count), limit, iterator, callback); }; async.seq = function (/* functions... */) { var fns = arguments; return _restParam(function (args) { var that = this; var callback = args[args.length - 1]; if (typeof callback == 'function') { args.pop(); } else { callback = noop; } async.reduce(fns, args, function (newargs, fn, cb) { fn.apply(that, newargs.concat([_restParam(function (err, nextargs) { cb(err, nextargs); })])); }, function (err, results) { callback.apply(that, [err].concat(results)); }); }); }; async.compose = function (/* functions... */) { return async.seq.apply(null, Array.prototype.reverse.call(arguments)); }; function _applyEach(eachfn) { return _restParam(function(fns, args) { var go = _restParam(function(args) { var that = this; var callback = args.pop(); return eachfn(fns, function (fn, _, cb) { fn.apply(that, args.concat([cb])); }, callback); }); if (args.length) { return go.apply(this, args); } else { return go; } }); } async.applyEach = _applyEach(async.eachOf); async.applyEachSeries = _applyEach(async.eachOfSeries); async.forever = function (fn, callback) { var done = only_once(callback || noop); var task = ensureAsync(fn); function next(err) { if (err) { return done(err); } task(next); } next(); }; function ensureAsync(fn) { return _restParam(function (args) { var callback = args.pop(); args.push(function () { var innerArgs = arguments; if (sync) { async.setImmediate(function () { callback.apply(null, innerArgs); }); } else { callback.apply(null, innerArgs); } }); var sync = true; fn.apply(this, args); sync = false; }); } async.ensureAsync = ensureAsync; async.constant = _restParam(function(values) { var args = [null].concat(values); return function (callback) { return callback.apply(this, args); }; }); async.wrapSync = async.asyncify = function asyncify(func) { return _restParam(function (args) { var callback = args.pop(); var result; try { result = func.apply(this, args); } catch (e) { return callback(e); } // if result is Promise object if (_isObject(result) && typeof result.then === "function") { result.then(function(value) { callback(null, value); })["catch"](function(err) { callback(err.message ? err : new Error(err)); }); } else { callback(null, result); } }); }; // Node.js if (typeof module === 'object' && module.exports) { module.exports = async; } // AMD / RequireJS else if (typeof define === 'function' && define.amd) { define('async', function () { return async; }); } // included directly via <script> tag else { root.async = async; } }()); ;(function (factory) { 'use strict'; if (typeof define === 'function' && define.amd) { define('sha1',[], factory); } else { window.sha1 = factory(); } })(function () { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS PUB 180-1 * Copyright (C) Paul Johnston 2000. * See http://pajhome.org.uk/site/legal.html for details. * * Modified by Tom Wu (tjw@cs.stanford.edu) for the * SRP JavaScript implementation. */ var sha1 = function() { /* * Convert a 32-bit number to a hex string with ms-byte first */ var hex_chr = "0123456789abcdef"; function hex(num) { var str = ""; for (var j = 7; j >= 0; j--) str += hex_chr.charAt((num >> (j * 4)) & 0x0F); return str; } /* * Convert a string to a sequence of 16-word blocks, stored as an array. * Append padding bits and the length, as described in the SHA1 standard. */ function str2blks_SHA1(str) { var nblk = ((str.length + 8) >> 6) + 1; var blks = new Array(nblk * 16); for (var i = 0; i < nblk * 16; i++) blks[i] = 0; for (i = 0; i < str.length; i++) blks[i >> 2] |= str.charCodeAt(i) << (24 - (i % 4) * 8); blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8); blks[nblk * 16 - 1] = str.length * 8; return blks; } /* * Input is in hex format - trailing odd nibble gets a zero appended. */ function hex2blks_SHA1(hex) { var len = (hex.length + 1) >> 1; var nblk = ((len + 8) >> 6) + 1; var blks = new Array(nblk * 16); for (var i = 0; i < nblk * 16; i++) blks[i] = 0; for (i = 0; i < len; i++) blks[i >> 2] |= parseInt(hex.substr(2 * i, 2), 16) << (24 - (i % 4) * 8); blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8); blks[nblk * 16 - 1] = len * 8; return blks; } function ba2blks_SHA1(ba, off, len) { var nblk = ((len + 8) >> 6) + 1; var blks = new Array(nblk * 16); for (var i = 0; i < nblk * 16; i++) blks[i] = 0; for (i = 0; i < len; i++) blks[i >> 2] |= (ba[off + i] & 0xFF) << (24 - (i % 4) * 8); blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8); blks[nblk * 16 - 1] = len * 8; return blks; } /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left */ function rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } /* * Perform the appropriate triplet combination function for the current * iteration */ function ft(t, b, c, d) { if (t < 20) return (b & c) | ((~b) & d); if (t < 40) return b ^ c ^ d; if (t < 60) return (b & c) | (b & d) | (c & d); return b ^ c ^ d; } /* * Determine the appropriate additive constant for the current iteration */ function kt(t) { return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514; } /* * Take a string and return the hex representation of its SHA-1. */ function calcSHA1(str) { return calcSHA1Blks(str2blks_SHA1(str)); } function calcSHA1Hex(str) { return calcSHA1Blks(hex2blks_SHA1(str)); } function calcSHA1BA(ba) { return calcSHA1Blks(ba2blks_SHA1(ba, 0, ba.length)); } function calcSHA1BAEx(ba, off, len) { return calcSHA1Blks(ba2blks_SHA1(ba, off, len)); } function calcSHA1Blks(x) { var s = calcSHA1Raw(x); return hex(s[0]) + hex(s[1]) + hex(s[2]) + hex(s[3]) + hex(s[4]); } function calcSHA1Raw(x) { var w = new Array(80); var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; var e = -1009589776; for (var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; var olde = e; for (var j = 0; j < 80; j++) { var t; if (j < 16) w[j] = x[i + j]; else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); t = add(add(rol(a, 5), ft(j, b, c, d)), add(add(e, w[j]), kt(j))); e = d; d = c; c = rol(b, 30); b = a; a = t; } a = add(a, olda); b = add(b, oldb); c = add(c, oldc); d = add(d, oldd); e = add(e, olde); } return new Array(a, b, c, d, e); } function core_sha1(x, len) { x[len >> 5] |= 0x80 << (24 - len % 32); x[((len + 64 >> 9) << 4) + 15] = len; return calcSHA1Raw(x); } return { calcSHA1: calcSHA1, calcSHA1Hex: calcSHA1Hex, calcSHA1BA: calcSHA1BA, calcSHA1BAEx: calcSHA1BAEx } } return sha1(); }); ;(function (factory) { 'use strict'; if (typeof define === 'function' && define.amd) { define('sjcl', [], factory); } else { window.sjcl = factory(); } })(function () { // SJCL configured with: // --without-all --with-sha256 --with-aes --with-random --with-bitArray --with-codecHex --with-codecBase64 --compress=none /** @fileOverview Javascript cryptography implementation. * * Crush to remove comments, shorten variable names and * generally reduce transmission size. * * @author Emily Stark * @author Mike Hamburg * @author Dan Boneh */ "use strict"; /*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */ /*global document, window, escape, unescape, module, require, Uint32Array */ /** @namespace The Stanford Javascript Crypto Library, top-level namespace. */ var sjcl = { /** @namespace Symmetric ciphers. */ cipher: {}, /** @namespace Hash functions. Right now only SHA256 is implemented. */ hash: {}, /** @namespace Key exchange functions. Right now only SRP is implemented. */ keyexchange: {}, /** @namespace Block cipher modes of operation. */ mode: {}, /** @namespace Miscellaneous. HMAC and PBKDF2. */ misc: {}, /** * @namespace Bit array encoders and decoders. * * @description * The members of this namespace are functions which translate between * SJCL's bitArrays and other objects (usually strings). Because it * isn't always clear which direction is encoding and which is decoding, * the method names are "fromBits" and "toBits". */ codec: {}, /** @namespace Exceptions. */ exception: { /** @constructor Ciphertext is corrupt. */ corrupt: function (message) { this.toString = function () { return "CORRUPT: " + this.message; }; this.message = message; }, /** @constructor Invalid parameter. */ invalid: function (message) { this.toString = function () { return "INVALID: " + this.message; }; this.message = message; }, /** @constructor Bug or missing feature in SJCL. @constructor */ bug: function (message) { this.toString = function () { return "BUG: " + this.message; }; this.message = message; }, /** @constructor Something isn't ready. */ notReady: function (message) { this.toString = function () { return "NOT READY: " + this.message; }; this.message = message; } } }; /** @fileOverview Arrays of bits, encoded as arrays of Numbers. * * @author Emily Stark * @author Mike Hamburg * @author Dan Boneh */ /** @namespace Arrays of bits, encoded as arrays of Numbers. * * @description * <p> * These objects are the currency accepted by SJCL's crypto functions. * </p> * * <p> * Most of our crypto primitives operate on arrays of 4-byte words internally, * but many of them can take arguments that are not a multiple of 4 bytes. * This library encodes arrays of bits (whose size need not be a multiple of 8 * bits) as arrays of 32-bit words. The bits are packed, big-endian, into an * array of words, 32 bits at a time. Since the words are double-precision * floating point numbers, they fit some extra data. We use this (in a private, * possibly-changing manner) to encode the number of bits actually present * in the last word of the array. * </p> * * <p> * Because bitwise ops clear this out-of-band data, these arrays can be passed * to ciphers like AES which want arrays of words. * </p> */ sjcl.bitArray = { /** * Array slices in units of bits. * @param {bitArray} a The array to slice. * @param {Number} bstart The offset to the start of the slice, in bits. * @param {Number} bend The offset to the end of the slice, in bits. If this is undefined, * slice until the end of the array. * @return {bitArray} The requested slice. */ bitSlice: function (a, bstart, bend) { a = sjcl.bitArray._shiftRight(a.slice(bstart / 32), 32 - (bstart & 31)).slice(1); return (bend === undefined) ? a : sjcl.bitArray.clamp(a, bend - bstart); }, /** * Extract a number packed into a bit array. * @param {bitArray} a The array to slice. * @param {Number} bstart The offset to the start of the slice, in bits. * @param {Number} length The length of the number to extract. * @return {Number} The requested slice. */ extract: function (a, bstart, blength) { // FIXME: this Math.floor is not necessary at all, but for some reason // seems to suppress a bug in the Chromium JIT. var x, sh = Math.floor((-bstart - blength) & 31); if ((bstart + blength - 1 ^ bstart) & -32) { // it crosses a boundary x = (a[bstart / 32 | 0] << (32 - sh)) ^ (a[bstart / 32 + 1 | 0] >>> sh); } else {