Rabbit.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. (function(){
  2. var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
  3. // Shortcuts
  4. var util = C.util,
  5. charenc = C.charenc,
  6. UTF8 = charenc.UTF8,
  7. Binary = charenc.Binary;
  8. // Inner state
  9. var x = [],
  10. c = [],
  11. b;
  12. var Rabbit = C.Rabbit = {
  13. /**
  14. * Public API
  15. */
  16. encrypt: function (message, password) {
  17. var
  18. // Convert to bytes
  19. m = UTF8.stringToBytes(message),
  20. // Generate random IV
  21. iv = util.randomBytes(8),
  22. // Generate key
  23. k = password.constructor == String ?
  24. // Derive key from passphrase
  25. C.PBKDF2(password, iv, 32, { asBytes: true }) :
  26. // else, assume byte array representing cryptographic key
  27. password;
  28. // Encrypt
  29. Rabbit._rabbit(m, k, util.bytesToWords(iv));
  30. // Return ciphertext
  31. return util.bytesToBase64(iv.concat(m));
  32. },
  33. decrypt: function (ciphertext, password) {
  34. var
  35. // Convert to bytes
  36. c = util.base64ToBytes(ciphertext),
  37. // Separate IV and message
  38. iv = c.splice(0, 8),
  39. // Generate key
  40. k = password.constructor == String ?
  41. // Derive key from passphrase
  42. C.PBKDF2(password, iv, 32, { asBytes: true }) :
  43. // else, assume byte array representing cryptographic key
  44. password;
  45. // Decrypt
  46. Rabbit._rabbit(c, k, util.bytesToWords(iv));
  47. // Return plaintext
  48. return UTF8.bytesToString(c);
  49. },
  50. /**
  51. * Internal methods
  52. */
  53. // Encryption/decryption scheme
  54. _rabbit: function (m, k, iv) {
  55. Rabbit._keysetup(k);
  56. if (iv) Rabbit._ivsetup(iv);
  57. for (var s = [], i = 0; i < m.length; i++) {
  58. if (i % 16 == 0) {
  59. // Iterate the system
  60. Rabbit._nextstate();
  61. // Generate 16 bytes of pseudo-random data
  62. s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16);
  63. s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16);
  64. s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16);
  65. s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16);
  66. // Swap endian
  67. for (var j = 0; j < 4; j++) {
  68. s[j] = ((s[j] << 8) | (s[j] >>> 24)) & 0x00FF00FF |
  69. ((s[j] << 24) | (s[j] >>> 8)) & 0xFF00FF00;
  70. }
  71. // Convert words to bytes
  72. for (var b = 120; b >= 0; b -= 8)
  73. s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF;
  74. }
  75. m[i] ^= s[i % 16];
  76. }
  77. },
  78. // Key setup scheme
  79. _keysetup: function (k) {
  80. // Generate initial state values
  81. x[0] = k[0];
  82. x[2] = k[1];
  83. x[4] = k[2];
  84. x[6] = k[3];
  85. x[1] = (k[3] << 16) | (k[2] >>> 16);
  86. x[3] = (k[0] << 16) | (k[3] >>> 16);
  87. x[5] = (k[1] << 16) | (k[0] >>> 16);
  88. x[7] = (k[2] << 16) | (k[1] >>> 16);
  89. // Generate initial counter values
  90. c[0] = util.rotl(k[2], 16);
  91. c[2] = util.rotl(k[3], 16);
  92. c[4] = util.rotl(k[0], 16);
  93. c[6] = util.rotl(k[1], 16);
  94. c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF);
  95. c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF);
  96. c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF);
  97. c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF);
  98. // Clear carry bit
  99. b = 0;
  100. // Iterate the system four times
  101. for (var i = 0; i < 4; i++) Rabbit._nextstate();
  102. // Modify the counters
  103. for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7];
  104. },
  105. // IV setup scheme
  106. _ivsetup: function (iv) {
  107. // Generate four subvectors
  108. var i0 = util.endian(iv[0]),
  109. i2 = util.endian(iv[1]),
  110. i1 = (i0 >>> 16) | (i2 & 0xFFFF0000),
  111. i3 = (i2 << 16) | (i0 & 0x0000FFFF);
  112. // Modify counter values
  113. c[0] ^= i0;
  114. c[1] ^= i1;
  115. c[2] ^= i2;
  116. c[3] ^= i3;
  117. c[4] ^= i0;
  118. c[5] ^= i1;
  119. c[6] ^= i2;
  120. c[7] ^= i3;
  121. // Iterate the system four times
  122. for (var i = 0; i < 4; i++) Rabbit._nextstate();
  123. },
  124. // Next-state function
  125. _nextstate: function () {
  126. // Save old counter values
  127. for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i];
  128. // Calculate new counter values
  129. c[0] = (c[0] + 0x4D34D34D + b) >>> 0;
  130. c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0;
  131. c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0;
  132. c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0;
  133. c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0;
  134. c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0;
  135. c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0;
  136. c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0;
  137. b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0;
  138. // Calculate the g-values
  139. for (var g = [], i = 0; i < 8; i++) {
  140. var gx = (x[i] + c[i]) >>> 0;
  141. // Construct high and low argument for squaring
  142. var ga = gx & 0xFFFF,
  143. gb = gx >>> 16;
  144. // Calculate high and low result of squaring
  145. var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb,
  146. gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0;
  147. // High XOR low
  148. g[i] = gh ^ gl;
  149. }
  150. // Calculate new state values
  151. x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16));
  152. x[1] = g[1] + ((g[0] << 8) | (g[0] >>> 24)) + g[7];
  153. x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16));
  154. x[3] = g[3] + ((g[2] << 8) | (g[2] >>> 24)) + g[1];
  155. x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16));
  156. x[5] = g[5] + ((g[4] << 8) | (g[4] >>> 24)) + g[3];
  157. x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16));
  158. x[7] = g[7] + ((g[6] << 8) | (g[6] >>> 24)) + g[5];
  159. }
  160. };
  161. })();