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