diff --git a/src/modules/_Crypto/include/rc4.h b/src/modules/_Crypto/include/rc4.h
new file mode 100644
index 0000000000000000000000000000000000000000..00d44f506897938429470251026834221c832117
--- /dev/null
+++ b/src/modules/_Crypto/include/rc4.h
@@ -0,0 +1,18 @@
+/* rc4.h */
+
+#ifndef RC4_H_INCLUDED
+#define RC4_H_INCLUDED
+
+struct rc4_ctx {
+  unsigned INT8 S[256];
+  unsigned INT8 i, j;
+};
+
+#if 0
+void rc4_init(struct rc4_ctx *ctx);
+#endif
+
+void rc4_set_key(struct rc4_ctx *ctx, const unsigned INT8 *key, INT32 len);
+void rc4_crypt(struct rc4_ctx *ctx, unsigned INT8 *dest, const unsigned INT8 *src, INT32 len);
+
+#endif /* RC4_H_INCLUDED */
diff --git a/src/modules/_Crypto/lib/rc4.c b/src/modules/_Crypto/lib/rc4.c
new file mode 100644
index 0000000000000000000000000000000000000000..a3bf04b7c688066a1b1bb86cb8fc064b7a6c6ab3
--- /dev/null
+++ b/src/modules/_Crypto/lib/rc4.c
@@ -0,0 +1,52 @@
+/* rc4.c
+ *
+ */
+
+#include "types.h"
+#include <rc4.h>
+
+#define SWAP(a,b) (a ^= b, b ^= a, a ^= b)
+
+#if 0
+void rc4_init(struct rc4_ctx *ctx)
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    ctx->S[i] = i;
+  ctx->i = ctx->j = 0;
+}
+#endif
+
+void rc4_set_key(struct rc4_ctx *ctx, const unsigned INT8 *key, INT32 len)
+{
+  register unsigned i, j;
+  INT32 k;
+
+  /* Initialize context */
+  for (i = 0; i < 256; i++)
+    ctx->S[i] = i;
+
+  /* Expand key */
+  for (i = j = k = 0; i < 256; i++)
+    {
+      j += ctx->S[i] + key[k];
+      SWAP(ctx->S[i], ctx->S[j]);
+      k = (k+1) % len; /* Repeat key if needed */
+    }
+  ctx->j = j; ctx->i = 0;
+}
+
+void rc4_crypt(struct rc4_ctx *ctx, unsigned INT8 *dest, const unsigned INT8 *src, INT32 len)
+{
+  register unsigned INT8 i,j; /* Depends on the 8-bitness of these variables */
+
+  i = ctx->i; j = ctx->j;
+  while(len--)
+    {
+      i = (i + 1);
+      j = (j + ctx->S[i]);
+      SWAP(ctx->S[i], ctx->S[j]);
+      *dest++ = *src++ ^ ctx->S[ (ctx->S[i] + ctx->S[j]) ];
+    }
+  ctx->i = i; ctx->j = j;
+}
diff --git a/src/modules/_Crypto/rc4.c b/src/modules/_Crypto/rc4.c
new file mode 100644
index 0000000000000000000000000000000000000000..457e159a323db3df7979645edde7b65803482a51
--- /dev/null
+++ b/src/modules/_Crypto/rc4.c
@@ -0,0 +1,125 @@
+/* rc4.c
+ *
+ * Written by Niels M�ller
+ */
+
+
+#include "global.h"
+#include "svalue.h"
+#include "string.h"
+#include "pike_types.h"
+#include "stralloc.h"
+#include "object.h"
+#include "interpret.h"
+#include "program.h"
+#include "error.h"
+#include "las.h"
+
+#include "rc4.h"
+
+/* Module specific includes */
+#include "precompiled_crypto.h"
+
+#define THIS ((struct rc4_ctx *)(fp->current_storage))
+
+struct program *pike_rc4_program;
+
+void init_pike_rc4(struct object *o)
+{
+  MEMSET(THIS, 0, sizeof(struct rc4_ctx));
+}
+
+void exit_pike_rc4(struct object *o)
+{
+  MEMSET(THIS, 0, sizeof(struct rc4_ctx));
+}
+
+/* string name(void) */
+static void f_name(INT32 args)
+{
+  if (args) {
+    error("Too many arguments to rc4->name()\n");
+  }
+  push_string(make_shared_string("RC4"));
+}
+
+/* int query_key_length(void) */
+static void f_query_key_length(INT32 args)
+{
+  if (args) {
+    error("Too many arguments to rc4->query_key_length()\n");
+  }
+  push_int(0);
+}
+
+/* void set_key(string) */
+static void f_set_key(INT32 args)
+{
+  if (args != 1) {
+    error("Wrong number of args to rc4->set_key()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to rc4->set_key()\n");
+  }
+  rc4_set_key(THIS, (unsigned INT8 *) sp[-1].u.string->str, sp[-1].u.string->len);
+
+  pop_n_elems(args);
+  this_object()->refs++;
+  push_object(this_object());
+}
+
+/* string crypt(string) */
+static void f_crypt(INT32 args)
+{
+  int len;
+  struct pike_string *s;
+  
+  if (args != 1) {
+    error("Wrong number of arguemnts to rc4->crypt()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to rc4->crypt()\n");
+  }
+
+  len = sp[-1].u.string->len;
+
+  s = begin_shared_string(len);
+  rc4_crypt(THIS,
+	    (unsigned INT8 *) s->str,
+	    (unsigned INT8 *) sp[-1].u.string->str,
+	    len);
+  
+  pop_n_elems(args);
+  push_string(end_shared_string(s));
+}
+
+void MOD_INIT2(rc4)(void)
+{
+  /* add_efun()s */
+}
+
+void MOD_INIT(rc4)(void)
+{
+  start_new_program();
+  add_storage(sizeof(struct rc4_ctx));
+
+  add_function("name", f_name, "function(void:string)", OPT_TRY_OPTIMIZE);
+  add_function("query_key_length", f_query_key_length, "function(void:int)", OPT_TRY_OPTIMIZE);
+  add_function("set_encrypt_key", f_set_key, "function(string:object)", OPT_SIDE_EFFECT);
+  add_function("set_decrypt_key", f_set_key, "function(string:object)", OPT_SIDE_EFFECT);
+  add_function("crypt", f_crypt, "function(string:string)", OPT_EXTERNAL_DEPEND);
+
+  set_init_callback(init_pike_rc4);
+  set_exit_callback(exit_pike_rc4);
+
+  pike_rc4_program = end_c_program(MODULE_PREFIX "rc4");
+  pike_rc4_program->refs++;
+}
+
+void MOD_EXIT(rc4)(void)
+{
+  /* free_program()s */
+  free_program(pike_rc4_program);
+}
+
+