0

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

4
  • 1
    Please state all non-base library calls and fix code issues as object 'j' not found so that someone may replicate your problem. Commented Mar 6, 2020 at 8:55
  • 1
    I'm not a programmer in r but if I were, I would hope to find well indented & spaced out code. You're trying to do too much in one function, split it up! Commented Mar 6, 2020 at 8:56
  • 1
    Note that RC4 is mainly of historical interest by now. It is an easy cipher to implement, which makes it a good introduction to stream ciphers, I guess. But please don't use it in a modern protocol / use case. It has bias, a tricky key setup and doesn't allow a separate IV... Commented Mar 6, 2020 at 9:40
  • @MaartenBodewes I agree, though unfortunately it is still necessary to have an rc4 implementation for certain tasks such as reading old encrypted pdf files. I think the newer ones use AES Commented Mar 6, 2020 at 9:43

1 Answer 1

2

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 be s <- 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.

rc4 <- function(message, key)
{
  if(is.raw(message)) message <- as.integer(message)
  if(is.character(message)) message <- utf8ToInt(message)  
  key            <- utf8ToInt(key)
  key_length     <- length(key)
  message_length <- length(message)
  s              <- 0:255
  a <- b <- x <- y <- 0 

  if(key_length == 0) stop("No key given")
  if(message_length == 0) return("")

  for (i in seq_along(s))
  {
    b <- (key[a + 1] + s[i] + b) %% 256
    tmp <- s[i]
    s[i] <- s[b + 1]
    s[b + 1] <- tmp
    a <- (a + 1) %% key_length;
  }

  for (k in seq(message_length))
  {
    x1 <- x <- (x + 1) %% 256
    y1 <- y <- (s[x + 1] + y) %% 256
    tmp <- s[x1]
    s[x1] <- s[y1]
    tmp <- s[y1]
    message[k] = bitwXor(message[k], s[(s[x1 + 1] + s[y1 + 1]) %% 256]);
  }
  if(any(message < 9 | message > 127)) return(as.raw(message))
  return(intToUtf8(message))
}

So lets see if it works:

encrypted_message <- rc4("hello", "world")
encrypted_message
#> [1] b7 31 74 99 98

It should be reversible with the same key:

rc4(encrypted_message, "world")
#> [1] "hello"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.