diff --git a/doc/LICENSE.md b/doc/LICENSE.md index 9818518..f2e1d01 100644 --- a/doc/LICENSE.md +++ b/doc/LICENSE.md @@ -152,10 +152,18 @@ Both came with the following license: > OTHER DEALINGS IN THE FONT SOFTWARE. -Javascript MD5 Library +JavaScript xxtea library ====================== -Obtained from , which says: +Obtained from , +which says: -> The JavaScript MD5 script is released under the -> [MIT license](http://www.opensource.org/licenses/MIT). +> I offer these formulæ & scripts for free use and adaptation as my +> contribution to the open-source info-sphere from which I have +> received so much. You are welcome to re-use these scripts (under a +> simple [attribution](http://creativecommons.org/licenses/by/3.0/) +> license, without any warranty express or implied) provided solely +> that you retain my copyright notice and a link to this page. + +Confusingly, the code itself says "MIT License". Both are compatible +with the larger project, however. \ No newline at end of file diff --git a/www/res/md5.min.js b/www/res/md5.min.js deleted file mode 100644 index 3399bf4..0000000 --- a/www/res/md5.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t),e=(n>>16)+(t>>16)+(r>>16);return e<<16|65535&r}function r(n,t){return n<>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<>>9<<4)+14]=r;var e,i,a,h,d,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;et;t+=8)r+=String.fromCharCode(n[t>>5]>>>t%32&255);return r}function h(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;tt;t+=8)r[t>>5]|=(255&n.charCodeAt(t/8))<16&&(o=i(o,8*n.length)),r=0;16>r;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(h(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="0123456789abcdef",o="";for(r=0;r>>4&15)+e.charAt(15&t);return o}function v(n){return unescape(encodeURIComponent(n))}function m(n){return d(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this); -//# sourceMappingURL=md5.min.js.map diff --git a/www/res/xxtea.js b/www/res/xxtea.js new file mode 100644 index 0000000..05d21fd --- /dev/null +++ b/www/res/xxtea.js @@ -0,0 +1,208 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* Block TEA (xxtea) Tiny Encryption Algorithm (c) Chris Veness 2002-2014 / MIT Licence */ +/* - www.movable-type.co.uk/scripts/tea-block.html */ +/* */ +/* Algorithm: David Wheeler & Roger Needham, Cambridge University Computer Lab */ +/* http://www.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html (1994) */ +/* http://www.cl.cam.ac.uk/ftp/users/djw3/xtea.ps (1997) */ +/* http://www.cl.cam.ac.uk/ftp/users/djw3/xxtea.ps (1998) */ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +'use strict'; + + +/** + * Tiny Encryption Algorithm + * + * @namespace + */ +var Tea = {}; + + +/** + * Encrypts text using Corrected Block TEA (xxtea) algorithm. + * + * @param {string} plaintext - String to be encrypted (multi-byte safe). + * @param {string} password - Password to be used for encryption (1st 16 chars). + * @returns {string} Encrypted text (encoded as base64). + */ +Tea.encrypt = function(plaintext, password) { + plaintext = String(plaintext); + password = String(password); + + if (plaintext.length == 0) return(''); // nothing to encrypt + + // v is n-word data vector; converted to array of longs from UTF-8 string + var v = Tea.strToLongs(plaintext.utf8Encode()); + // k is 4-word key; simply convert first 16 chars of password as key + var k = Tea.strToLongs(password.utf8Encode().slice(0,16)); + + v = Tea.encode(v, k); + + // convert array of longs to string + var ciphertext = Tea.longsToStr(v); + + // convert binary string to base64 ascii for safe transport + return ciphertext.base64Encode(); +}; + + +/** + * Decrypts text using Corrected Block TEA (xxtea) algorithm. + * + * @param {string} ciphertext - String to be decrypted. + * @param {string} password - Password to be used for decryption (1st 16 chars). + * @returns {string} Decrypted text. + */ +Tea.decrypt = function(ciphertext, password) { + ciphertext = String(ciphertext); + password = String(password); + + if (ciphertext.length == 0) return(''); + + // v is n-word data vector; converted to array of longs from base64 string + var v = Tea.strToLongs(ciphertext.base64Decode()); + // k is 4-word key; simply convert first 16 chars of password as key + var k = Tea.strToLongs(password.utf8Encode().slice(0,16)); + + v = Tea.decode(v, k); + + var plaintext = Tea.longsToStr(v); + + // strip trailing null chars resulting from filling 4-char blocks: + plaintext = plaintext.replace(/\0+$/,''); + + return plaintext.utf8Decode(); +}; + + +/** + * XXTEA: encodes array of unsigned 32-bit integers using 128-bit key. + * + * @param {number[]} v - Data vector. + * @param {number[]} k - Key. + * @returns {number[]} Encoded vector. + */ +Tea.encode = function(v, k) { + if (v.length < 2) v[1] = 0; // algorithm doesn't work for n<2 so fudge by adding a null + var n = v.length; + + var z = v[n-1], y = v[0], delta = 0x9E3779B9; + var mx, e, q = Math.floor(6 + 52/n), sum = 0; + + while (q-- > 0) { // 6 + 52/n operations gives between 6 & 32 mixes on each word + sum += delta; + e = sum>>>2 & 3; + for (var p = 0; p < n; p++) { + y = v[(p+1)%n]; + mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z); + z = v[p] += mx; + } + } + + return v; +}; + + +/** + * XXTEA: decodes array of unsigned 32-bit integers using 128-bit key. + * + * @param {number[]} v - Data vector. + * @param {number[]} k - Key. + * @returns {number[]} Decoded vector. + */ +Tea.decode = function(v, k) { + var n = v.length; + + var z = v[n-1], y = v[0], delta = 0x9E3779B9; + var mx, e, q = Math.floor(6 + 52/n), sum = q*delta; + + while (sum != 0) { + e = sum>>>2 & 3; + for (var p = n-1; p >= 0; p--) { + z = v[p>0 ? p-1 : n-1]; + mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z); + y = v[p] -= mx; + } + sum -= delta; + } + + return v; +}; + + +/** + * Converts string to array of longs (each containing 4 chars). + * @private + */ +Tea.strToLongs = function(s) { + // note chars must be within ISO-8859-1 (Unicode code-point <= U+00FF) to fit 4/long + var l = new Array(Math.ceil(s.length/4)); + for (var i=0; i>>8 & 0xFF, l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF); + } + return a.join(''); // use Array.join() for better performance than repeated string appends +}; + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +/** Extend String object with method to encode multi-byte string to utf8 + * - monsur.hossa.in/2012/07/20/utf-8-in-javascript.html */ +if (typeof String.prototype.utf8Encode == 'undefined') { + String.prototype.utf8Encode = function() { + return unescape( encodeURIComponent( this ) ); + }; +} + +/** Extend String object with method to decode utf8 string to multi-byte */ +if (typeof String.prototype.utf8Decode == 'undefined') { + String.prototype.utf8Decode = function() { + try { + return decodeURIComponent( escape( this ) ); + } catch (e) { + return this; // invalid UTF-8? return as-is + } + }; +} + + +/** Extend String object with method to encode base64 + * - developer.mozilla.org/en-US/docs/Web/API/window.btoa, nodejs.org/api/buffer.html + * note: if btoa()/atob() are not available (eg IE9-), try github.com/davidchambers/Base64.js */ +if (typeof String.prototype.base64Encode == 'undefined') { + String.prototype.base64Encode = function() { + if (typeof btoa != 'undefined') return btoa(this); // browser + if (typeof Buffer != 'undefined') return new Buffer(this, 'binary').toString('base64'); // Node.js + throw new Error('No Base64 Encode'); + }; +} + +/** Extend String object with method to decode base64 */ +if (typeof String.prototype.base64Decode == 'undefined') { + String.prototype.base64Decode = function() { + if (typeof atob != 'undefined') return atob(this); // browser + if (typeof Buffer != 'undefined') return new Buffer(this, 'base64').toString('binary'); // Node.js + throw new Error('No Base64 Decode'); + }; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +if (typeof module != 'undefined' && module.exports) module.exports = Tea; // CommonJS export