Last active
March 6, 2021 11:26
-
-
Save bryc/46026abe00f18461a2d6dc23245ea6f3 to your computer and use it in GitHub Desktop.
RC4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function rc4(key, data) { | |
var output = [], S = [], tmp, i, j = 0; | |
for (i = 0; i < 256; i++) { | |
S[i] = i; | |
} | |
for (i = 0; i < 256; i++) { | |
j = (j + S[i] + key[i % key.length]) % 256; | |
tmp = S[i]; | |
S[i] = S[j]; | |
S[j] = tmp; | |
} | |
i = 0, j = 0; | |
for (var k = 0; k < data.length; k++) { | |
i = (i + 1) % 256; | |
j = (j + S[i]) % 256; | |
tmp = S[i]; | |
S[i] = S[j]; | |
S[j] = tmp; | |
output[k] = data[k] ^ S[(S[i] + S[j]) % 256]; | |
} | |
return output; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function rc4(key, msg) { | |
function swap(S, i, j) {var tmp=S[j];S[j]=S[i];S[i]=tmp;} | |
function ksa(key) { | |
for (var S=[],i=j=0; i<256; i++) {S[i] = i;} | |
for (i = 0; i < 256; i++) { | |
j = (j + S[i] + key[i % key.length]) % 256; | |
swap(S, i, j); | |
} return S; | |
} | |
var output = [], S = ksa(key); | |
for (var k=j=i=0; k < msg.length; k++) { | |
i = (i + 1) % 256; | |
j = (j + S[i]) % 256; | |
swap(S, i, j); | |
output[k] = msg[k] ^ S[(S[i] + S[j]) % 256]; | |
} | |
return output; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// S2 = KSA(S1) - S2 produced by key of entire S1 table (better, but possibly incorrect) | |
function rc4a(key, msg) { | |
function swap(S, i, j) { | |
var tmp = S[j]; S[j] = S[i]; S[i] = tmp; | |
} | |
function xorout(msg, keystream) { | |
for(var cipher = [], i = 0; i < msg.length; i++) { | |
cipher[i] = msg[i] ^ keystream[i]; | |
} return cipher; | |
} | |
function rc4_ksa(key) { | |
for (var S=[],i=j=0; i<256; i++) {S[i] = i;} | |
for (i = 0; i < 256; i++) { | |
j = (j + S[i] + key[i % key.length]) % 256; | |
swap(S, i, j); | |
} return S; | |
} | |
function rc4a_prga(S1, S2) { | |
var keystream = []; | |
for (var k=j1=j2=i=0; k<msg.length; k+=2) { | |
i = (i + 1) % 256; | |
j1 = (j1 + S1[i]) % 256; | |
swap(S1, i, j1); | |
keystream[k] = S2[(S1[i] + S1[j1]) % 256]; | |
if(msg[k + 1] === undefined) {break;} // skip j2 if next byte in msg doesn't exist | |
j2 = (j2 + S2[i]) % 256; | |
swap(S2, i, j2); | |
keystream[k + 1] = S1[(S2[i] + S2[j2]) % 256]; | |
} return keystream; | |
} | |
var S1 = rc4_ksa(key); | |
var S2 = rc4_ksa(S1); | |
var keystream = rc4a_prga(S1, S2); | |
var output = { | |
plain: msg, | |
cipher: xorout(msg, keystream), // final xor of msg<->keystream | |
keystream: keystream, | |
S1: S1, | |
S2: S2, | |
key1: key | |
} | |
return output; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// S1 = S2 (a popular, yet incorrect approach) | |
function rc4a(key, msg) { | |
function swap(S, i, j) { | |
var tmp = S[j]; S[j] = S[i]; S[i] = tmp; | |
} | |
function xorout(msg, keystream) { | |
for(var cipher = [], i = 0; i < msg.length; i++) { | |
cipher[i] = msg[i] ^ keystream[i]; | |
} return cipher; | |
} | |
function rc4_ksa(key) { | |
for (var S=[],i=j=0; i<256; i++) {S[i] = i;} | |
for (i = 0; i < 256; i++) { | |
j = (j + S[i] + key[i % key.length]) % 256; | |
swap(S, i, j); | |
} return S; | |
} | |
function rc4a_prga(S1, S2) { | |
var keystream = []; | |
for (var k=j1=j2=i=0; k<msg.length; k+=2) { | |
i = (i + 1) % 256; | |
j1 = (j1 + S1[i]) % 256; | |
swap(S1, i, j1); | |
keystream[k] = S2[(S1[i] + S1[j1]) % 256]; | |
if(msg[k + 1] === undefined) {break;} // skip j2 if next byte in msg doesn't exist | |
j2 = (j2 + S2[i]) % 256; | |
swap(S2, i, j2); | |
keystream[k + 1] = S1[(S2[i] + S2[j2]) % 256]; | |
} return keystream; | |
} | |
var S1 = rc4_ksa(key); | |
var S2 = rc4_ksa(key); | |
var keystream = rc4a_prga(S1, S2); | |
var output = { | |
plain: msg, | |
cipher: xorout(msg, keystream), // final xor of msg<->keystream | |
keystream: keystream, | |
S1: S1, | |
S2: S2, | |
key1: key | |
} | |
return output; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function rc4a(key, msg) { | |
function swap(S, i, j) { | |
var tmp = S[j]; S[j] = S[i]; S[i] = tmp; | |
} | |
function xorout(msg, keystream) { | |
for(var cipher = [], i = 0; i < msg.length; i++) { | |
cipher[i] = msg[i] ^ keystream[i]; | |
} return cipher; | |
} | |
function rc4_ksa(key) { | |
for (var S=[],i=j=0; i<256; i++) {S[i] = i;} | |
for (i = 0; i < 256; i++) { | |
j = (j + S[i] + key[i % key.length]) % 256; | |
swap(S, i, j); | |
} return S; | |
} | |
function rc4_prga(S) { | |
var keystream = []; | |
for (var k=i=j=0; k<key.length; k++) { | |
i = (i + 1) % 256; | |
j = (j + S[i]) % 256; | |
swap(S, i, j); | |
keystream[k] = S[(S[i] + S[j]) % 256]; | |
} return keystream; | |
} | |
function rc4a_prga(S1, S2) { | |
var keystream = []; | |
for (var k=j1=j2=i=0; k<msg.length; k+=2) { | |
i = (i + 1) % 256; | |
j1 = (j1 + S1[i]) % 256; | |
swap(S1, i, j1); | |
keystream[k] = S2[(S1[i] + S1[j1]) % 256]; | |
if(msg[k + 1] === undefined) {break;} // skip j2 if next byte in msg doesn't exist | |
j2 = (j2 + S2[i]) % 256; | |
swap(S2, i, j2); | |
keystream[k + 1] = S1[(S2[i] + S2[j2]) % 256]; | |
} return keystream; | |
} | |
var S1 = rc4_ksa(key); | |
var key2 = rc4_prga(S1.slice(0)); // Clone S1 so rc4_prga doesn't alter original | |
var S2 = rc4_ksa(key2); | |
var keystream = rc4a_prga(S1, S2); | |
var output = { | |
plain: msg, | |
cipher: xorout(msg, keystream), // final xor of msg<->keystream | |
keystream: keystream, | |
S1: S1, | |
S2: S2, | |
key1: key, | |
key2: key2 | |
} | |
return output; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment