Wheeler & Needham’s Tiny Encryption Algorithm in js form

simple but powerful encryption algorithm which provides strong encryption in just a few lines of concise, clear code

Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.greatest.deepsurf.us/scripts/12124/71602/Wheeler%20%20Needham%E2%80%99s%20Tiny%20Encryption%20Algorithm%20in%20js%20form.js

  1. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  2. /* Block TEA (xxtea) Tiny Encryption Algorithm (c) Chris Veness 2002-2014 / MIT Licence */
  3. /* - www.movable-type.co.uk/scripts/tea-block.html */
  4. /* */
  5. /* Algorithm: David Wheeler & Roger Needham, Cambridge University Computer Lab */
  6. /* http://www.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html (1994) */
  7. /* http://www.cl.cam.ac.uk/ftp/users/djw3/xtea.ps (1997) */
  8. /* http://www.cl.cam.ac.uk/ftp/users/djw3/xxtea.ps (1998) */
  9. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  10.  
  11. /* jshint node:true *//* global define, escape, unescape, btoa, atob */
  12. 'use strict';
  13.  
  14.  
  15. /**
  16. * Tiny Encryption Algorithm
  17. *
  18. * @namespace
  19. */
  20. var Tea = {};
  21.  
  22.  
  23. /**
  24. * Encrypts text using Corrected Block TEA (xxtea) algorithm.
  25. *
  26. * @param {string} plaintext - String to be encrypted (multi-byte safe).
  27. * @param {string} password - Password to be used for encryption (1st 16 chars).
  28. * @returns {string} Encrypted text (encoded as base64).
  29. */
  30. Tea.encrypt = function(plaintext, password) {
  31. plaintext = String(plaintext);
  32. password = String(password);
  33.  
  34. if (plaintext.length == 0) return(''); // nothing to encrypt
  35.  
  36. // v is n-word data vector; converted to array of longs from UTF-8 string
  37. var v = Tea.strToLongs(plaintext.utf8Encode());
  38. // k is 4-word key; simply convert first 16 chars of password as key
  39. var k = Tea.strToLongs(password.utf8Encode().slice(0,16));
  40. var n = v.length;
  41.  
  42. v = Tea.encode(v, k);
  43.  
  44. // convert array of longs to string
  45. var ciphertext = Tea.longsToStr(v);
  46.  
  47. // convert binary string to base64 ascii for safe transport
  48. return ciphertext.base64Encode();
  49. };
  50.  
  51.  
  52. /**
  53. * Decrypts text using Corrected Block TEA (xxtea) algorithm.
  54. *
  55. * @param {string} ciphertext - String to be decrypted.
  56. * @param {string} password - Password to be used for decryption (1st 16 chars).
  57. * @returns {string} Decrypted text.
  58. */
  59. Tea.decrypt = function(ciphertext, password) {
  60. ciphertext = String(ciphertext);
  61. password = String(password);
  62.  
  63. if (ciphertext.length == 0) return('');
  64.  
  65. // v is n-word data vector; converted to array of longs from base64 string
  66. var v = Tea.strToLongs(ciphertext.base64Decode());
  67. // k is 4-word key; simply convert first 16 chars of password as key
  68. var k = Tea.strToLongs(password.utf8Encode().slice(0,16));
  69. var n = v.length;
  70.  
  71. v = Tea.decode(v, k);
  72.  
  73. var plaintext = Tea.longsToStr(v);
  74.  
  75. // strip trailing null chars resulting from filling 4-char blocks:
  76. plaintext = plaintext.replace(/\0+$/,'');
  77.  
  78. return plaintext.utf8Decode();
  79. };
  80.  
  81.  
  82. /**
  83. * XXTEA: encodes array of unsigned 32-bit integers using 128-bit key.
  84. *
  85. * @param {number[]} v - Data vector.
  86. * @param {number[]} k - Key.
  87. * @returns {number[]} Encoded vector.
  88. */
  89. Tea.encode = function(v, k) {
  90. if (v.length < 2) v[1] = 0; // algorithm doesn't work for n<2 so fudge by adding a null
  91. var n = v.length;
  92.  
  93. var z = v[n-1], y = v[0], delta = 0x9E3779B9;
  94. var mx, e, q = Math.floor(6 + 52/n), sum = 0;
  95.  
  96. while (q-- > 0) { // 6 + 52/n operations gives between 6 & 32 mixes on each word
  97. sum += delta;
  98. e = sum>>>2 & 3;
  99. for (var p = 0; p < n; p++) {
  100. y = v[(p+1)%n];
  101. mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
  102. z = v[p] += mx;
  103. }
  104. }
  105.  
  106. return v;
  107. };
  108.  
  109.  
  110. /**
  111. * XXTEA: decodes array of unsigned 32-bit integers using 128-bit key.
  112. *
  113. * @param {number[]} v - Data vector.
  114. * @param {number[]} k - Key.
  115. * @returns {number[]} Decoded vector.
  116. */
  117. Tea.decode = function(v, k) {
  118. var n = v.length;
  119.  
  120. var z = v[n-1], y = v[0], delta = 0x9E3779B9;
  121. var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;
  122.  
  123. while (sum != 0) {
  124. e = sum>>>2 & 3;
  125. for (var p = n-1; p >= 0; p--) {
  126. z = v[p>0 ? p-1 : n-1];
  127. mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
  128. y = v[p] -= mx;
  129. }
  130. sum -= delta;
  131. }
  132.  
  133. return v;
  134. };
  135.  
  136.  
  137. /**
  138. * Converts string to array of longs (each containing 4 chars).
  139. * @private
  140. */
  141. Tea.strToLongs = function(s) {
  142. // note chars must be within ISO-8859-1 (Unicode code-point <= U+00FF) to fit 4/long
  143. var l = new Array(Math.ceil(s.length/4));
  144. for (var i=0; i<l.length; i++) {
  145. // note little-endian encoding - endianness is irrelevant as long as it matches longsToStr()
  146. l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) +
  147. (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
  148. }
  149. return l; // note running off the end of the string generates nulls since bitwise operators
  150. }; // treat NaN as 0
  151.  
  152.  
  153. /**
  154. * Converts array of longs to string.
  155. * @private
  156. */
  157. Tea.longsToStr = function(l) {
  158. var a = new Array(l.length);
  159. for (var i=0; i<l.length; i++) {
  160. a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF, l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
  161. }
  162. return a.join(''); // use Array.join() for better performance than repeated string appends
  163. };
  164.  
  165.  
  166. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  167.  
  168.  
  169. /** Extend String object with method to encode multi-byte string to utf8
  170. * - monsur.hossa.in/2012/07/20/utf-8-in-javascript.html */
  171. if (typeof String.prototype.utf8Encode == 'undefined') {
  172. String.prototype.utf8Encode = function() {
  173. return unescape( encodeURIComponent( this ) );
  174. };
  175. }
  176.  
  177. /** Extend String object with method to decode utf8 string to multi-byte */
  178. if (typeof String.prototype.utf8Decode == 'undefined') {
  179. String.prototype.utf8Decode = function() {
  180. try {
  181. return decodeURIComponent( escape( this ) );
  182. } catch (e) {
  183. return this; // invalid UTF-8? return as-is
  184. }
  185. };
  186. }
  187.  
  188.  
  189. /** Extend String object with method to encode base64
  190. * - developer.mozilla.org/en-US/docs/Web/API/window.btoa, nodejs.org/api/buffer.html
  191. * note: if btoa()/atob() are not available (eg IE9-), try github.com/davidchambers/Base64.js */
  192. if (typeof String.prototype.base64Encode == 'undefined') {
  193. String.prototype.base64Encode = function() {
  194. if (typeof btoa != 'undefined') return btoa(this); // browser
  195. if (typeof Buffer != 'undefined') return new Buffer(this, 'utf8').toString('base64'); // Node.js
  196. throw new Error('No Base64 Encode');
  197. };
  198. }
  199.  
  200. /** Extend String object with method to decode base64 */
  201. if (typeof String.prototype.base64Decode == 'undefined') {
  202. String.prototype.base64Decode = function() {
  203. if (typeof atob != 'undefined') return atob(this); // browser
  204. if (typeof Buffer != 'undefined') return new Buffer(this, 'base64').toString('utf8'); // Node.js
  205. throw new Error('No Base64 Decode');
  206. };
  207. }
  208.  
  209.  
  210. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  211. if (typeof module != 'undefined' && module.exports) module.exports = Tea; // CommonJS export
  212. if (typeof define == 'function' && define.amd) define([''], function() { return Tea; }); // AMD