I am trying to create a R function that will take a seed,and key length to generate a RC4 keystream.
The following is what I have so far:
library(numbers)
library(seqinr)
library(compositions)
rc4_genkey <- function(seed,keylength){
keystream <- vector(mode="integer", length=keylength)
# initialized S vector
s <- vector(mode="integer", length=255)
for(i in 1:255){
s[i + 1] = i+1
}
# initialize k vector with seed
key <- utf8ToInt(seed)
n <- length(key)
k <- vector(mode="integer", length=256)
for (i in 1:255){
k[i + 1] = key[mod(i+1, n)+1]
}
# Rc4 algorithm randomize 2 with 256 iterations
for (i in 1:255){
j <- (mod(j + s[i+1] + k[i+1], 256))
swap(s[i + 1], s[j])
}
# generate keystream of keystream length
for(i in 0:length(keystream)){
i <- mod((i + 1),256)
j <- mod((j + s[i]), 256)
swap(s[i+1],s[j+1])
t <- mod((s[i] + s[j]),256)
k[i] <- s[t]
keystream[i] <- k[i]
}
}
Now every time I run the function, it keeps telling me
"s[i + 1] <- s[j + 1] : replacement has length zero"
Hoping to get a little help to fix up this to run a proper rc4 encrpytion
I think you have made quite a few errors here: rc4 is a symmetric cypher, so your rc4 function should take a message and key (not key length), and return a stream of bytes.
I'm guessing you have tried to translate this function from a lower-level, zero-indexed language into R. Your creation of the state vector
s, for example (which in rc4 should start off as 0 to 255) should just bes <- 0:255, not written with a loop.I have previously written a C++ implementation of rc4, so I have translated it to R here for you.
This function will return a raw vector if there are non-Ascii elements in the result, and a character string otherwise, so most of the time your encrypted message will be in raw format and an unencrypted message will be a character string. It would be easy enough to modify it to accept and return only raw vectors though.
So lets see if it works:
It should be reversible with the same key: