Skip to content

Instantly share code, notes, and snippets.

@drazisil
Last active March 21, 2018 00:49
Show Gist options
  • Save drazisil/73c238655276d213c8efcd3365486096 to your computer and use it in GitHub Desktop.
Save drazisil/73c238655276d213c8efcd3365486096 to your computer and use it in GitHub Desktop.
Pure JS Implementation of RC4
class MyRC4 {
constructor(key) {
const keyBytes = Buffer.from(key)
const keyLength = keyBytes.length
this.m_state = Array(256)
this.m_x = 0
this.m_y = 0
let counter
for (let counter = 0; counter < 256; counter++) {
this.m_state[counter] = counter;
}
// console.log(`Initial sBox after KSA: ${this.m_state}`)
let index1 = 0
let j = 0
for (let counter = 0; counter < 256; counter++) {
j = (j + this.m_state[counter] + keyBytes[counter % keyLength]) % 256
// console.log(`counter: ${counter}, j: ${j}`)
this.swapByte(counter, j)
if (index1 >= keyLength) index1 = 0;
}
console.log(`Initial sBox: ${this.m_state}`)
}
swapByte(b1, b2) {
let t1 = this.m_state[b1]
this.m_state[b1] = this.m_state[b2]
this.m_state[b2] = t1
}
processByte(inByte) {
this.m_x++
this.m_y += this.m_state[this.m_x]
this.swapByte(this.m_x, this.m_y)
return inByte ^ ((this.m_state[(this.m_state[this.m_x] + this.m_state[this.m_y]) & 256]) % 256)
}
processString(inString) {
let inBytes = Buffer.from(inString)
let idx1 = 0
let idx2 = 0
let strLength = inBytes.length
let output = Buffer.alloc(strLength)
let s = this.m_state
let x = this.m_x
let y = this.m_y
while (strLength--) {
x = (x + 1) & 0xff
let a = s[x]
y = (y + a) & 0xff
let b = s[y]
s[x] = b
s[y] = a
output[idx1++] = inBytes[idx2++] ^ s[(a+b) & 0xff]
}
this.m_x = x
this.m_y = y
return output
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment