michael@14: /* michael@14: * OTPWCalc - One time password challenge response calculator client michael@14: * Copyright © 2013 Michael Schloh von Bennewitz michael@14: * michael@14: * OTPWCalc is free software: you can redistribute it and/or modify michael@14: * it under the terms of the European Union Public Licence, either michael@14: * version 1.1 of the license, or (at your option) any later version. michael@14: * michael@14: * OTPWCalc is distributed in the hope that it will be useful, michael@14: * but WITHOUT ANY WARRANTY; without even the implied warranty michael@14: * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See michael@14: * the European Union Public License for more details. michael@14: * michael@14: * You should have received a copy of the European Union Public michael@14: * Licence along with OTPWCalc. If not, please refer to michael@14: * . michael@14: * michael@14: * This file is part of project OTWPCalc, a one time password challenge michael@14: * response calculator client and is found at http://otpwcalc.europalab.com/ michael@14: * michael@14: * otpalg.js: ECMA JavaScript implementation michael@14: */ michael@14: michael@14: // 0; --i) { t = mdxfold(coremd4(t, 64)); } michael@14: return t; michael@14: } michael@14: michael@14: function genotpmd5(secret, seed, n) { michael@14: var t = seed.toString().toLowerCase() + secret; michael@14: t = mdxfold(coremd5(str2binl(t), t.length * 8)); michael@14: for (var i = n; i > 0; --i) { t = mdxfold(coremd5(t, 64)); } michael@14: return t; michael@14: } michael@14: michael@14: function genotpsha1(secret, seed, n) { michael@14: var t = seed.toString().toLowerCase() + secret; michael@14: t = sha1fold(coresha1(str2binb(t), t.length * 8)); michael@14: for (var i = n; i > 0; --i) { t = sha1fold(coresha1(t, 64)); } michael@14: t = invertendian(t, true); michael@14: return t; michael@14: } michael@14: michael@14: function genotprmd160(secret, seed, n) { michael@14: var t = seed.toString().toLowerCase() + secret; michael@14: t = rmd160fold(corermd160(str2binl(t), t.length * 8)); michael@14: for (var i = n; i > 0; --i) { t = rmd160fold(corermd160(t, 64)); } michael@14: return t; michael@14: } michael@14: michael@14: function genotpmultmd4(secret, seed, n, m) { michael@14: var res = Array(); var lim = n - m + 1; michael@14: var t = seed.toString().toLowerCase() + secret; michael@14: t = mdxfold(coremd4(str2binl(t), t.length * 8)); michael@14: if (lim == 0) res[0] = t; michael@14: for (var i = 1; i <= n; ++i) { michael@14: t = mdxfold(coremd4(t, 64)); michael@14: if (i >= lim) res[i-lim] = t; michael@14: } michael@14: return res; michael@14: } michael@14: michael@14: function genotpmultmd5(secret, seed, n, m) { michael@14: var res = Array(); var lim = n - m + 1; michael@14: var t = seed.toString().toLowerCase() + secret; michael@14: t = mdxfold(coremd5(str2binl(t), t.length * 8)); michael@14: if (lim == 0) res[0] = t; michael@14: for (var i = 1; i <= n; ++i) { michael@14: t = mdxfold(coremd5(t, 64)); michael@14: if (i >= lim) res[i-lim] = t; michael@14: } michael@14: return res; michael@14: } michael@14: michael@14: function genotpmultsha1(secret, seed, n, m) { michael@14: var res = Array(); var lim = n - m + 1; michael@14: var t = seed.toString().toLowerCase() + secret; michael@14: t = sha1fold(coresha1(str2binb(t), t.length * 8)); michael@14: if (lim == 0) res[0] = invertendian(t, false); michael@14: for (var i = 1; i <= n; ++i) { michael@14: t = sha1fold(coresha1(t, 64)); michael@14: if (i >= lim) res[i-lim] = invertendian(t, false); michael@14: } michael@14: return res; michael@14: } michael@14: michael@14: function genotpmultrmd160(secret, seed, n, m) { michael@14: var res = Array(); var lim = n - m + 1; michael@14: var t = seed.toString().toLowerCase() + secret; michael@14: t = rmd160fold(corermd160(str2binl(t), t.length * 8)); michael@14: if (lim == 0) res[0] = t; michael@14: for (var i = 1; i <= n; ++i) { michael@14: t = rmd160fold(corermd160(t, 64)); michael@14: if (i >= lim) res[i-lim] = t; michael@14: } michael@14: return res; michael@14: } michael@14: michael@14: function mdxfold(h) { return Array(h[0] ^ h[2], h[1] ^ h[3]); } michael@14: michael@14: function sha1fold(h) { michael@14: h = invertendian(h, true); michael@14: return Array(h[0] ^ h[2] ^ h[4], h[1] ^ h[3]); michael@14: } michael@14: michael@14: function rmd160fold(h) { return Array(h[0] ^ h[2] ^ h[4], h[1] ^ h[3]); } michael@14: michael@14: function invertendian(a, inpl) { michael@14: var t = inpl ? a : Array(a.length); michael@14: for (var i = 0; i < a.length; ++i) { michael@14: var t1 = (a[i] & 0xff) << 24; michael@14: var t2 = ((a[i] >> 8) & 0xff) << 16; michael@14: var t3 = ((a[i] >> 16) & 0xff) << 8; michael@14: var t4 = (a[i] >> 24) & 0xff; michael@14: t[i] = t1 | t2 | t3 | t4; michael@14: } michael@14: return t; michael@14: } michael@14: michael@14: function arrtoboth(a) { return arrtosix(a) + " (" + arrtohex(a) + ")"; } michael@14: michael@14: function arrtohex(a) { michael@14: var s = ""; michael@14: for (var i = 0; i < 2; ++i) { michael@14: for (var j = 0; j < 4; ++j) { michael@14: var t = (a[i] >> (8*j)) & 0xff; michael@14: t = t.toString(16).toUpperCase(); michael@14: s += (t.length == 1) ? ('0' + t) : t; // 1 octet = 2 hex digits michael@14: if (j % 2 == 1) s += ' '; michael@14: } michael@14: } michael@14: return s.substr(0, s.length-1); // drop the last space michael@14: } michael@14: michael@14: function arrtosix(h) { michael@14: var s = ""; michael@14: var parity = 0; michael@14: for (var i = 0; i < 2; ++i) { michael@14: for (var j = 0; j < 32; j += 2) { michael@14: parity += (h[i] >> j) & 0x3; michael@14: } michael@14: } michael@14: var ind; michael@14: ind = (h[0] & 0xff) << 3; michael@14: ind |= (h[0] >> 13) & 0x7; michael@14: s += words[ind] + " "; michael@14: ind = ((h[0] >> 8) & 0x1f) << 6; michael@14: ind |= (h[0] >> 18) & 0x3f; michael@14: s += words[ind] + " "; michael@14: ind = ((h[0] >> 16) & 0x3) << 9; michael@14: ind |= ((h[0] >> 24) & 0xff) << 1; michael@14: ind |= (h[1] >> 7) & 0x1; michael@14: s += words[ind] + " "; michael@14: ind = (h[1] & 0x7f) << 4; michael@14: ind |= (h[1] >> 12) & 0xf; michael@14: s += words[ind] + " "; michael@14: ind = ((h[1] >> 8) & 0xf) << 7; michael@14: ind |= (h[1] >> 17) & 0x7f; michael@14: s += words[ind] + " "; michael@14: ind = ((h[1] >> 16) & 0x1) << 10; michael@14: ind |= ((h[1] >> 24) & 0xff) << 2; michael@14: ind |= (parity & 0x03); michael@14: s += words[ind]; michael@14: return s; michael@14: } michael@14: // ]]>