github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/app/lib/crypto1/rabbit/rabbit.js (about) 1 /*! 2 * Crypto-JS v1.1.0 3 * http://code.google.com/p/crypto-js/ 4 * Copyright (c) 2009, Jeff Mott. All rights reserved. 5 * http://code.google.com/p/crypto-js/wiki/License 6 */ 7 (function(){ 8 9 // Shortcut 10 var util = Crypto.util; 11 12 // Inner state 13 var x = [], 14 c = [], 15 b; 16 17 var Rabbit = Crypto.Rabbit = { 18 19 /** 20 * Public API 21 */ 22 23 encrypt: function (message, password) { 24 25 var 26 27 // Convert to bytes 28 m = util.stringToBytes(message), 29 30 // Generate random IV 31 iv = util.randomBytes(8), 32 33 // Generate key 34 k = Crypto.PBKDF2(password, util.bytesToString(iv), 16, { asBytes: true }); 35 36 // Encrypt 37 Rabbit._rabbit(m, k, util.bytesToWords(iv)); 38 39 // Return ciphertext 40 return util.bytesToBase64(iv.concat(m)); 41 42 }, 43 44 decrypt: function (ciphertext, password) { 45 46 var 47 48 // Convert to bytes 49 c = util.base64ToBytes(ciphertext), 50 51 // Separate IV and message 52 iv = c.splice(0, 8), 53 54 // Generate key 55 k = Crypto.PBKDF2(password, util.bytesToString(iv), 16, { asBytes: true }); 56 57 // Decrypt 58 Rabbit._rabbit(c, k, util.bytesToWords(iv)); 59 60 // Return plaintext 61 return util.bytesToString(c); 62 63 }, 64 65 66 /** 67 * Internal methods 68 */ 69 70 // Encryption/decryption scheme 71 _rabbit: function (m, k, iv) { 72 73 Rabbit._keysetup(k); 74 if (iv) Rabbit._ivsetup(iv); 75 76 for (var s = [], i = 0; i < m.length; i++) { 77 78 if (i % 16 == 0) { 79 80 // Iterate the system 81 Rabbit._nextstate(); 82 83 // Generate 16 bytes of pseudo-random data 84 s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16); 85 s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16); 86 s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16); 87 s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16); 88 89 // Swap endian 90 for (var j = 0; j < 4; j++) { 91 s[j] = ((s[j] << 8) | (s[j] >>> 24)) & 0x00FF00FF | 92 ((s[j] << 24) | (s[j] >>> 8)) & 0xFF00FF00; 93 } 94 95 // Convert words to bytes 96 for (var b = 120; b >= 0; b -= 8) 97 s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF; 98 99 } 100 101 m[i] ^= s[i % 16]; 102 103 } 104 105 }, 106 107 // Key setup scheme 108 _keysetup: function (k) { 109 110 // Generate initial state values 111 x[0] = k[0]; 112 x[2] = k[1]; 113 x[4] = k[2]; 114 x[6] = k[3]; 115 x[1] = (k[3] << 16) | (k[2] >>> 16); 116 x[3] = (k[0] << 16) | (k[3] >>> 16); 117 x[5] = (k[1] << 16) | (k[0] >>> 16); 118 x[7] = (k[2] << 16) | (k[1] >>> 16); 119 120 // Generate initial counter values 121 c[0] = util.rotl(k[2], 16); 122 c[2] = util.rotl(k[3], 16); 123 c[4] = util.rotl(k[0], 16); 124 c[6] = util.rotl(k[1], 16); 125 c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF); 126 c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF); 127 c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF); 128 c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF); 129 130 // Clear carry bit 131 b = 0; 132 133 // Iterate the system four times 134 for (var i = 0; i < 4; i++) Rabbit._nextstate(); 135 136 // Modify the counters 137 for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7]; 138 139 }, 140 141 // IV setup scheme 142 _ivsetup: function (iv) { 143 144 // Generate four subvectors 145 var i0 = util.endian(iv[0]), 146 i2 = util.endian(iv[1]), 147 i1 = (i0 >>> 16) | (i2 & 0xFFFF0000), 148 i3 = (i2 << 16) | (i0 & 0x0000FFFF); 149 150 // Modify counter values 151 c[0] ^= i0; 152 c[1] ^= i1; 153 c[2] ^= i2; 154 c[3] ^= i3; 155 c[4] ^= i0; 156 c[5] ^= i1; 157 c[6] ^= i2; 158 c[7] ^= i3; 159 160 // Iterate the system four times 161 for (var i = 0; i < 4; i++) Rabbit._nextstate(); 162 163 }, 164 165 // Next-state function 166 _nextstate: function () { 167 168 // Save old counter values 169 for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i]; 170 171 // Calculate new counter values 172 c[0] = (c[0] + 0x4D34D34D + b) >>> 0; 173 c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0; 174 c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0; 175 c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0; 176 c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0; 177 c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0; 178 c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0; 179 c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0; 180 b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0; 181 182 // Calculate the g-values 183 for (var g = [], i = 0; i < 8; i++) { 184 185 var gx = (x[i] + c[i]) >>> 0; 186 187 // Construct high and low argument for squaring 188 var ga = gx & 0xFFFF, 189 gb = gx >>> 16; 190 191 // Calculate high and low result of squaring 192 var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb, 193 gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0; 194 195 // High XOR low 196 g[i] = gh ^ gl; 197 198 } 199 200 // Calculate new state values 201 x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16)); 202 x[1] = g[1] + ((g[0] << 8) | (g[0] >>> 24)) + g[7]; 203 x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16)); 204 x[3] = g[3] + ((g[2] << 8) | (g[2] >>> 24)) + g[1]; 205 x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16)); 206 x[5] = g[5] + ((g[4] << 8) | (g[4] >>> 24)) + g[3]; 207 x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16)); 208 x[7] = g[7] + ((g[6] << 8) | (g[6] >>> 24)) + g[5]; 209 210 } 211 212 }; 213 214 })();