diff --git a/helper.pl b/helper.pl
index 22fac916a..5b1a1b2c4 100755
--- a/helper.pl
+++ b/helper.pl
@@ -62,7 +62,6 @@ sub check_source {
           $file !~ m|src/ciphers/.*\.c$| &&
           $file !~ m|src/hashes/.*\.c$| &&
           $file !~ m|src/math/.+_desc.c$| &&
-          $file !~ m|src/stream/sober128/sober128_stream.c$| &&
           $l =~ /^static(\s+[a-zA-Z0-9_]+)+\s+([^_][a-zA-Z0-9_]+)\s*\(/) {
         push @{$troubles->{staticfunc_name}}, "$lineno($2)";
       }
diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj
index 8bc1c62c9..190cef2b1 100644
--- a/libtomcrypt_VS2008.vcproj
+++ b/libtomcrypt_VS2008.vcproj
@@ -2647,25 +2647,61 @@
 				Name="rabbit"
 				>
 				<File
-					RelativePath="src\stream\rabbit\rabbit.c"
+					RelativePath="src\stream\rabbit\rabbit_common.h"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\rabbit\rabbit_crypt.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\rabbit\rabbit_done.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\rabbit\rabbit_keystream.c"
 					>
 				</File>
 				<File
 					RelativePath="src\stream\rabbit\rabbit_memory.c"
 					>
 				</File>
+				<File
+					RelativePath="src\stream\rabbit\rabbit_setiv.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\rabbit\rabbit_setup.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\rabbit\rabbit_test.c"
+					>
+				</File>
 			</Filter>
 			<Filter
 				Name="rc4"
 				>
 				<File
-					RelativePath="src\stream\rc4\rc4_stream.c"
+					RelativePath="src\stream\rc4\rc4_stream_crypt.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\rc4\rc4_stream_done.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\rc4\rc4_stream_keystream.c"
 					>
 				</File>
 				<File
 					RelativePath="src\stream\rc4\rc4_stream_memory.c"
 					>
 				</File>
+				<File
+					RelativePath="src\stream\rc4\rc4_stream_setup.c"
+					>
+				</File>
 				<File
 					RelativePath="src\stream\rc4\rc4_test.c"
 					>
@@ -2719,13 +2755,33 @@
 				Name="sober128"
 				>
 				<File
-					RelativePath="src\stream\sober128\sober128_stream.c"
+					RelativePath="src\stream\sober128\sober128_stream_common.h"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\sober128\sober128_stream_crypt.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\sober128\sober128_stream_done.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\sober128\sober128_stream_keystream.c"
 					>
 				</File>
 				<File
 					RelativePath="src\stream\sober128\sober128_stream_memory.c"
 					>
 				</File>
+				<File
+					RelativePath="src\stream\sober128\sober128_stream_setiv.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\sober128\sober128_stream_setup.c"
+					>
+				</File>
 				<File
 					RelativePath="src\stream\sober128\sober128_test.c"
 					>
@@ -2779,13 +2835,33 @@
 				Name="sosemanuk"
 				>
 				<File
-					RelativePath="src\stream\sosemanuk\sosemanuk.c"
+					RelativePath="src\stream\sosemanuk\sosemanuk_common.h"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\sosemanuk\sosemanuk_crypt.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\sosemanuk\sosemanuk_done.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\sosemanuk\sosemanuk_keystream.c"
 					>
 				</File>
 				<File
 					RelativePath="src\stream\sosemanuk\sosemanuk_memory.c"
 					>
 				</File>
+				<File
+					RelativePath="src\stream\sosemanuk\sosemanuk_setiv.c"
+					>
+				</File>
+				<File
+					RelativePath="src\stream\sosemanuk\sosemanuk_setup.c"
+					>
+				</File>
 				<File
 					RelativePath="src\stream\sosemanuk\sosemanuk_test.c"
 					>
diff --git a/makefile.mingw b/makefile.mingw
index 9d0a70f9d..ceb0bd503 100644
--- a/makefile.mingw
+++ b/makefile.mingw
@@ -203,16 +203,24 @@ src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/so
 src/prngs/sprng.o src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
 src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
 src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit_crypt.o \
+src/stream/rabbit/rabbit_done.o src/stream/rabbit/rabbit_keystream.o src/stream/rabbit/rabbit_memory.o \
+src/stream/rabbit/rabbit_setiv.o src/stream/rabbit/rabbit_setup.o src/stream/rabbit/rabbit_test.o \
+src/stream/rc4/rc4_stream_crypt.o src/stream/rc4/rc4_stream_done.o \
+src/stream/rc4/rc4_stream_keystream.o src/stream/rc4/rc4_stream_memory.o \
+src/stream/rc4/rc4_stream_setup.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream_crypt.o \
+src/stream/sober128/sober128_stream_done.o src/stream/sober128/sober128_stream_keystream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_stream_setiv.o \
+src/stream/sober128/sober128_stream_setup.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk_crypt.o src/stream/sosemanuk/sosemanuk_done.o \
+src/stream/sosemanuk/sosemanuk_keystream.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_setiv.o src/stream/sosemanuk/sosemanuk_setup.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 #List of test objects to compile
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \
@@ -227,7 +235,8 @@ HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tom
 src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \
 src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h src/headers/tomcrypt_math.h \
 src/headers/tomcrypt_misc.h src/headers/tomcrypt_pk.h src/headers/tomcrypt_pkcs.h \
-src/headers/tomcrypt_prng.h
+src/headers/tomcrypt_prng.h src/stream/rabbit/rabbit_common.h \
+src/stream/sober128/sober128_stream_common.h src/stream/sosemanuk/sosemanuk_common.h
 
 HEADERS=$(HEADERS_PUB) src/headers/tomcrypt_private.h
 
diff --git a/makefile.msvc b/makefile.msvc
index 6b2c10061..816de1001 100644
--- a/makefile.msvc
+++ b/makefile.msvc
@@ -196,16 +196,24 @@ src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/pr
 src/prngs/sprng.obj src/prngs/yarrow.obj src/stream/chacha/chacha_crypt.obj src/stream/chacha/chacha_done.obj \
 src/stream/chacha/chacha_ivctr32.obj src/stream/chacha/chacha_ivctr64.obj \
 src/stream/chacha/chacha_keystream.obj src/stream/chacha/chacha_memory.obj \
-src/stream/chacha/chacha_setup.obj src/stream/chacha/chacha_test.obj src/stream/rabbit/rabbit.obj \
-src/stream/rabbit/rabbit_memory.obj src/stream/rc4/rc4_stream.obj src/stream/rc4/rc4_stream_memory.obj \
-src/stream/rc4/rc4_test.obj src/stream/salsa20/salsa20_crypt.obj src/stream/salsa20/salsa20_done.obj \
-src/stream/salsa20/salsa20_ivctr64.obj src/stream/salsa20/salsa20_keystream.obj \
-src/stream/salsa20/salsa20_memory.obj src/stream/salsa20/salsa20_setup.obj \
-src/stream/salsa20/salsa20_test.obj src/stream/salsa20/xsalsa20_memory.obj \
-src/stream/salsa20/xsalsa20_setup.obj src/stream/salsa20/xsalsa20_test.obj \
-src/stream/sober128/sober128_stream.obj src/stream/sober128/sober128_stream_memory.obj \
-src/stream/sober128/sober128_test.obj src/stream/sosemanuk/sosemanuk.obj \
-src/stream/sosemanuk/sosemanuk_memory.obj src/stream/sosemanuk/sosemanuk_test.obj
+src/stream/chacha/chacha_setup.obj src/stream/chacha/chacha_test.obj src/stream/rabbit/rabbit_crypt.obj \
+src/stream/rabbit/rabbit_done.obj src/stream/rabbit/rabbit_keystream.obj src/stream/rabbit/rabbit_memory.obj \
+src/stream/rabbit/rabbit_setiv.obj src/stream/rabbit/rabbit_setup.obj src/stream/rabbit/rabbit_test.obj \
+src/stream/rc4/rc4_stream_crypt.obj src/stream/rc4/rc4_stream_done.obj \
+src/stream/rc4/rc4_stream_keystream.obj src/stream/rc4/rc4_stream_memory.obj \
+src/stream/rc4/rc4_stream_setup.obj src/stream/rc4/rc4_test.obj src/stream/salsa20/salsa20_crypt.obj \
+src/stream/salsa20/salsa20_done.obj src/stream/salsa20/salsa20_ivctr64.obj \
+src/stream/salsa20/salsa20_keystream.obj src/stream/salsa20/salsa20_memory.obj \
+src/stream/salsa20/salsa20_setup.obj src/stream/salsa20/salsa20_test.obj \
+src/stream/salsa20/xsalsa20_memory.obj src/stream/salsa20/xsalsa20_setup.obj \
+src/stream/salsa20/xsalsa20_test.obj src/stream/sober128/sober128_stream_crypt.obj \
+src/stream/sober128/sober128_stream_done.obj src/stream/sober128/sober128_stream_keystream.obj \
+src/stream/sober128/sober128_stream_memory.obj src/stream/sober128/sober128_stream_setiv.obj \
+src/stream/sober128/sober128_stream_setup.obj src/stream/sober128/sober128_test.obj \
+src/stream/sosemanuk/sosemanuk_crypt.obj src/stream/sosemanuk/sosemanuk_done.obj \
+src/stream/sosemanuk/sosemanuk_keystream.obj src/stream/sosemanuk/sosemanuk_memory.obj \
+src/stream/sosemanuk/sosemanuk_setiv.obj src/stream/sosemanuk/sosemanuk_setup.obj \
+src/stream/sosemanuk/sosemanuk_test.obj
 
 #List of test objects to compile
 TOBJECTS=tests/base16_test.obj tests/base32_test.obj tests/base64_test.obj tests/cipher_hash_test.obj \
@@ -220,7 +228,8 @@ HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tom
 src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \
 src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h src/headers/tomcrypt_math.h \
 src/headers/tomcrypt_misc.h src/headers/tomcrypt_pk.h src/headers/tomcrypt_pkcs.h \
-src/headers/tomcrypt_prng.h
+src/headers/tomcrypt_prng.h src/stream/rabbit/rabbit_common.h \
+src/stream/sober128/sober128_stream_common.h src/stream/sosemanuk/sosemanuk_common.h
 
 HEADERS=$(HEADERS_PUB) src/headers/tomcrypt_private.h
 
diff --git a/makefile.unix b/makefile.unix
index 20f9a0d9b..2d3b063bb 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -213,16 +213,24 @@ src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/so
 src/prngs/sprng.o src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
 src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
 src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit_crypt.o \
+src/stream/rabbit/rabbit_done.o src/stream/rabbit/rabbit_keystream.o src/stream/rabbit/rabbit_memory.o \
+src/stream/rabbit/rabbit_setiv.o src/stream/rabbit/rabbit_setup.o src/stream/rabbit/rabbit_test.o \
+src/stream/rc4/rc4_stream_crypt.o src/stream/rc4/rc4_stream_done.o \
+src/stream/rc4/rc4_stream_keystream.o src/stream/rc4/rc4_stream_memory.o \
+src/stream/rc4/rc4_stream_setup.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream_crypt.o \
+src/stream/sober128/sober128_stream_done.o src/stream/sober128/sober128_stream_keystream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_stream_setiv.o \
+src/stream/sober128/sober128_stream_setup.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk_crypt.o src/stream/sosemanuk/sosemanuk_done.o \
+src/stream/sosemanuk/sosemanuk_keystream.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_setiv.o src/stream/sosemanuk/sosemanuk_setup.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 #List of test objects to compile (all goes to libtomcrypt_prof.a)
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \
@@ -237,7 +245,8 @@ HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tom
 src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \
 src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h src/headers/tomcrypt_math.h \
 src/headers/tomcrypt_misc.h src/headers/tomcrypt_pk.h src/headers/tomcrypt_pkcs.h \
-src/headers/tomcrypt_prng.h
+src/headers/tomcrypt_prng.h src/stream/rabbit/rabbit_common.h \
+src/stream/sober128/sober128_stream_common.h src/stream/sosemanuk/sosemanuk_common.h
 
 HEADERS=$(HEADERS_PUB) src/headers/tomcrypt_private.h
 
diff --git a/makefile_include.mk b/makefile_include.mk
index 4bcec2206..e48badaa1 100644
--- a/makefile_include.mk
+++ b/makefile_include.mk
@@ -373,16 +373,24 @@ src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/so
 src/prngs/sprng.o src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
 src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
 src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit_crypt.o \
+src/stream/rabbit/rabbit_done.o src/stream/rabbit/rabbit_keystream.o src/stream/rabbit/rabbit_memory.o \
+src/stream/rabbit/rabbit_setiv.o src/stream/rabbit/rabbit_setup.o src/stream/rabbit/rabbit_test.o \
+src/stream/rc4/rc4_stream_crypt.o src/stream/rc4/rc4_stream_done.o \
+src/stream/rc4/rc4_stream_keystream.o src/stream/rc4/rc4_stream_memory.o \
+src/stream/rc4/rc4_stream_setup.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream_crypt.o \
+src/stream/sober128/sober128_stream_done.o src/stream/sober128/sober128_stream_keystream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_stream_setiv.o \
+src/stream/sober128/sober128_stream_setup.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk_crypt.o src/stream/sosemanuk/sosemanuk_done.o \
+src/stream/sosemanuk/sosemanuk_keystream.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_setiv.o src/stream/sosemanuk/sosemanuk_setup.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 # List of test objects to compile (all goes to libtomcrypt_prof.a)
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \
@@ -397,7 +405,8 @@ HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tom
 src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \
 src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h src/headers/tomcrypt_math.h \
 src/headers/tomcrypt_misc.h src/headers/tomcrypt_pk.h src/headers/tomcrypt_pkcs.h \
-src/headers/tomcrypt_prng.h
+src/headers/tomcrypt_prng.h src/stream/rabbit/rabbit_common.h \
+src/stream/sober128/sober128_stream_common.h src/stream/sosemanuk/sosemanuk_common.h
 
 HEADERS=$(HEADERS_PUB) src/headers/tomcrypt_private.h
 
diff --git a/src/stream/rabbit/rabbit.c b/src/stream/rabbit/rabbit.c
deleted file mode 100644
index 9d7e0dff2..000000000
--- a/src/stream/rabbit/rabbit.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- */
-
-/******************************************************************************
- * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
- * and should run on any conforming C implementation (C90 or later).
- *
- * This implementation supports any key length up to 128 bits (16 bytes) and
- * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
- * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
- * may be any length up to 8 bytes and will be padded out to 8 bytes.
- *
- * The eSTREAM submission was rather picky about the calling sequence of
- * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
- * calling ECRYPT_process_blocks() multiple times for a multiple of whole
- * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
- * were supported correctly.  This implementation handles the keystream
- * differently and rabbit_crypt() may be called as many times as desired,
- * crypting any number of bytes each time.
- *
- *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
- *
- * NB: One of the test vectors distributed by the eSTREAM site in the file
- *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
- *     in that ZIP file, the 3rd line in "out1" should be
- *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
- *
- * Here is the original legal notice accompanying the Rabbit submission
- * to the EU eSTREAM competition.
- *---------------------------------------------------------------------------
- * Copyright (C) Cryptico A/S. All rights reserved.
- *
- * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
- *
- * This software is developed by Cryptico A/S and/or its suppliers.
- * All title and intellectual property rights in and to the software,
- * including but not limited to patent rights and copyrights, are owned
- * by Cryptico A/S and/or its suppliers.
- *
- * The software may be used solely for non-commercial purposes
- * without the prior written consent of Cryptico A/S. For further
- * information on licensing terms and conditions please contact
- * Cryptico A/S at info@cryptico.com
- *
- * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
- * are either trademarks or registered trademarks of Cryptico A/S.
- *
- * Cryptico A/S shall not in any way be liable for any use of this
- * software. The software is provided "as is" without any express or
- * implied warranty.
- *---------------------------------------------------------------------------
- * On October 6, 2008, Rabbit was "released into the public domain and
- * may be used freely for any purpose."
- *   http://www.ecrypt.eu.org/stream/rabbitpf.html
- *   https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
- ******************************************************************************/
-
-
-#include "tomcrypt_private.h"
-
-#ifdef LTC_RABBIT
-
-/* local/private prototypes  (NB: rabbit_ctx and rabbit_state are different)  */
-static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x);
-static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance);
-static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out);
-
-/* -------------------------------------------------------------------------- */
-
-/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
-/* the upper 32 bits XOR the lower 32 bits */
-static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x)
-{
-   ulong32 a, b, h, l;
-
-   /* Construct high and low argument for squaring */
-   a = x &  0xFFFF;
-   b = x >> 16;
-
-   /* Calculate high and low result of squaring */
-   h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b;
-   l = x * x;
-
-   /* Return high XOR low */
-   return (ulong32)(h^l);
-}
-
-/* -------------------------------------------------------------------------- */
-
-/* Calculate the next internal state */
-static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance)
-{
-   ulong32 g[8], c_old[8], i;
-
-   /* Save old counter values */
-   for (i=0; i<8; i++) {
-      c_old[i] = p_instance->c[i];
-   }
-
-   /* Calculate new counter values */
-   p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry);
-   p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0]));
-   p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1]));
-   p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2]));
-   p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3]));
-   p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4]));
-   p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5]));
-   p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6]));
-   p_instance->carry = (p_instance->c[7] < c_old[7]);
-
-   /* Calculate the g-values */
-   for (i=0;i<8;i++) {
-      g[i] = _rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i]));
-   }
-
-   /* Calculate new state values */
-   p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16));
-   p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]);
-   p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16));
-   p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]);
-   p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16));
-   p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]);
-   p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16));
-   p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out)
-{
-    ulong32 *ptr;
-
-    /* Iterate the work context once */
-    _rabbit_next_state(&(st->work_ctx));
-
-    /* Generate 16 bytes of pseudo-random data */
-    ptr = (ulong32*)&(st->work_ctx.x);
-    STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0);
-    STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4);
-    STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8);
-    STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12);
-}
-
-/* -------------------------------------------------------------------------- */
-
-/* Key setup */
-int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen)
-{
-   ulong32 k0, k1, k2, k3, i;
-   unsigned char  tmpkey[16] = {0};
-
-   LTC_ARGCHK(st != NULL);
-   LTC_ARGCHK(key != NULL);
-   LTC_ARGCHK(keylen <= 16);
-
-   /* init state */
-   XMEMSET(st, 0, sizeof(rabbit_state));
-
-   /* pad key in tmpkey */
-   XMEMCPY(tmpkey, key, keylen);
-
-   /* Generate four subkeys */
-   LOAD32L(k0, tmpkey+ 0);
-   LOAD32L(k1, tmpkey+ 4);
-   LOAD32L(k2, tmpkey+ 8);
-   LOAD32L(k3, tmpkey+12);
-
-#ifdef LTC_CLEAN_STACK
-   /* done with tmpkey, wipe it */
-   zeromem(tmpkey, sizeof(tmpkey));
-#endif
-
-   /* Generate initial state variables */
-   st->master_ctx.x[0] = k0;
-   st->master_ctx.x[2] = k1;
-   st->master_ctx.x[4] = k2;
-   st->master_ctx.x[6] = k3;
-   st->master_ctx.x[1] = (ulong32)(k3<<16) | (k2>>16);
-   st->master_ctx.x[3] = (ulong32)(k0<<16) | (k3>>16);
-   st->master_ctx.x[5] = (ulong32)(k1<<16) | (k0>>16);
-   st->master_ctx.x[7] = (ulong32)(k2<<16) | (k1>>16);
-
-   /* Generate initial counter values */
-   st->master_ctx.c[0] = ROLc(k2, 16);
-   st->master_ctx.c[2] = ROLc(k3, 16);
-   st->master_ctx.c[4] = ROLc(k0, 16);
-   st->master_ctx.c[6] = ROLc(k1, 16);
-   st->master_ctx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
-   st->master_ctx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
-   st->master_ctx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
-   st->master_ctx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
-
-   /* Clear carry bit */
-   st->master_ctx.carry = 0;
-
-   /* Iterate the master context four times */
-   for (i=0; i<4; i++) {
-      _rabbit_next_state(&(st->master_ctx));
-   }
-
-   /* Modify the counters */
-   for (i=0; i<8; i++) {
-      st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7];
-   }
-
-   /* Copy master instance to work instance */
-   for (i=0; i<8; i++) {
-      st->work_ctx.x[i] = st->master_ctx.x[i];
-      st->work_ctx.c[i] = st->master_ctx.c[i];
-   }
-   st->work_ctx.carry = st->master_ctx.carry;
-   /* ...and prepare block for crypt() */
-   XMEMSET(&(st->block), 0, sizeof(st->block));
-   st->unused = 0;
-
-   return CRYPT_OK;
-}
-
-/* -------------------------------------------------------------------------- */
-
-/* IV setup */
-int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen)
-{
-   ulong32 i0, i1, i2, i3, i;
-   unsigned char  tmpiv[8] = {0};
-
-   LTC_ARGCHK(st != NULL);
-   LTC_ARGCHK(iv != NULL || ivlen == 0);
-   LTC_ARGCHK(ivlen <= 8);
-
-   /* pad iv in tmpiv */
-   if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen);
-
-   /* Generate four subvectors */
-   LOAD32L(i0, tmpiv+0);
-   LOAD32L(i2, tmpiv+4);
-   i1 = (i0>>16) | (i2&0xFFFF0000);
-   i3 = (i2<<16) | (i0&0x0000FFFF);
-
-   /* Modify counter values */
-   st->work_ctx.c[0] = st->master_ctx.c[0] ^ i0;
-   st->work_ctx.c[1] = st->master_ctx.c[1] ^ i1;
-   st->work_ctx.c[2] = st->master_ctx.c[2] ^ i2;
-   st->work_ctx.c[3] = st->master_ctx.c[3] ^ i3;
-   st->work_ctx.c[4] = st->master_ctx.c[4] ^ i0;
-   st->work_ctx.c[5] = st->master_ctx.c[5] ^ i1;
-   st->work_ctx.c[6] = st->master_ctx.c[6] ^ i2;
-   st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3;
-
-   /* Copy state variables */
-   for (i=0; i<8; i++) {
-      st->work_ctx.x[i] = st->master_ctx.x[i];
-   }
-   st->work_ctx.carry = st->master_ctx.carry;
-
-   /* Iterate the work context four times */
-   for (i=0; i<4; i++) {
-      _rabbit_next_state(&(st->work_ctx));
-   }
-
-   /* reset keystream buffer and unused count */
-   XMEMSET(&(st->block), 0, sizeof(st->block));
-   st->unused = 0;
-
-   return CRYPT_OK;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Crypt a chunk of any size (encrypt/decrypt) */
-int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out)
-{
-   unsigned char buf[16];
-   unsigned long i, j;
-
-   if (inlen == 0) return CRYPT_OK; /* nothing to do */
-
-   LTC_ARGCHK(st        != NULL);
-   LTC_ARGCHK(in        != NULL);
-   LTC_ARGCHK(out       != NULL);
-
-   if (st->unused > 0) {
-      j = MIN(st->unused, inlen);
-      for (i = 0; i < j; ++i, st->unused--) out[i] = in[i] ^ st->block[16 - st->unused];
-      inlen -= j;
-      if (inlen == 0) return CRYPT_OK;
-      out += j;
-      in  += j;
-   }
-   for (;;) {
-     /* gen a block for buf */
-     _rabbit_gen_1_block(st, buf);
-     if (inlen <= 16) {
-       /* XOR and send to out */
-       for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
-       st->unused = 16 - inlen;
-       /* copy remainder to block */
-       for (i = inlen; i < 16; ++i) st->block[i] = buf[i];
-       return CRYPT_OK;
-     }
-     /* XOR entire buf and send to out */
-     for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i];
-     inlen -= 16;
-     out += 16;
-     in  += 16;
-   }
-}
-
-/* ------------------------------------------------------------------------- */
-
-int rabbit_keystream(rabbit_state *st, unsigned char *out, unsigned long outlen)
-{
-   if (outlen == 0) return CRYPT_OK; /* nothing to do */
-
-   LTC_ARGCHK(out != NULL);
-
-   XMEMSET(out, 0, outlen);
-   return rabbit_crypt(st, out, outlen, out);
-}
-
-/* -------------------------------------------------------------------------- */
-
-int rabbit_done(rabbit_state *st)
-{
-   LTC_ARGCHK(st != NULL);
-
-   zeromem(st, sizeof(rabbit_state));
-   return CRYPT_OK;
-}
-
-/* -------------------------------------------------------------------------- */
-
-int rabbit_test(void)
-{
-#ifndef LTC_TEST
-   return CRYPT_NOP;
-#else
-   rabbit_state st;
-   int err;
-   unsigned char out[1000] = { 0 };
-   {
-      /* all 3 tests use key and iv fm set 6, vector 3, the last vector in:
-         http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/rabbit/verified.test-vectors?rev=210&view=log
-      */
-
-      /* --- Test 1 (generate whole blocks) --------------------------------- */
-
-      {
-         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
-                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
-         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
-         char pt[64]        = { 0 };
-         unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
-                                0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
-                                0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
-                                0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
-                                0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D, 0x7C,
-                                0x0C, 0x10, 0x9B, 0x79, 0xD5, 0x74, 0x94, 0x39,
-                                0xB7, 0xEF, 0xA4, 0xC4, 0xC9, 0xC8, 0xD2, 0x9D,
-                                0xC5, 0xB3, 0x88, 0x83, 0x14, 0xA6, 0x81, 0x6F };
-         unsigned long ptlen = sizeof(pt);
-
-         /* crypt 64 nulls */
-         if ((err = rabbit_setup(&st, k, sizeof(k)))                   != CRYPT_OK) return err;
-         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                 != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt, ptlen, out)) != CRYPT_OK) return err;
-         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV1", 1))   return CRYPT_FAIL_TESTVECTOR;
-      }
-
-      /* --- Test 2 (generate unusual number of bytes each time) ------------ */
-
-      {
-         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
-                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
-         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
-         char          pt[39] = { 0 };
-         unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA,   0x96, 0xAF, 0xF6, 0xCA,
-                                0xCF, 0x2A, 0x45, 0x9A,   0x10, 0x2A, 0x7F, 0x78,
-                                0xCA, 0x98, 0x5C, 0xF8,   0xFD, 0xD1, 0x47, 0x40,
-                                0x18, 0x75, 0x8E, 0x36,   0xAE, 0x99, 0x23, 0xF5,
-                                0x19, 0xD1, 0x3D, 0x71,   0x8D, 0xAF, 0x8D };
-         unsigned long ptlen = sizeof(pt);
-
-         /* crypt piece by piece (hit at least one 16-byte boundary) */
-         if ((err = rabbit_setup(&st, k, sizeof(k)))                          != CRYPT_OK) return err;
-         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt,       5, out))      != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt +  5, 11, out +  5)) != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 16, 14, out + 16)) != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 30,  2, out + 30)) != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 32,  7, out + 32)) != CRYPT_OK) return err;
-         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV2", 1))   return CRYPT_FAIL_TESTVECTOR;
-      }
-
-      /* --- Test 3 (use non-null data) ------------------------------------- */
-
-      {
-         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
-                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
-         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
-         char          pt[] = "Kilroy was here, there, and everywhere!";
-         unsigned char ct[] = { 0x2a, 0x55, 0xdc, 0xc8,   0xf9, 0xd6, 0xd6, 0xbd,
-                                0xae, 0x59, 0x65, 0xf2,   0x75, 0x58, 0x1a, 0x54,
-                                0xea, 0xec, 0x34, 0x9d,   0x8f, 0xb4, 0x6b, 0x60,
-                                0x79, 0x1b, 0xea, 0x16,   0xcb, 0xef, 0x46, 0x87,
-                                0x60, 0xa6, 0x55, 0x14,   0xff, 0xca, 0xac };
-         unsigned long ptlen = strlen(pt);
-         unsigned char out2[1000] = { 0 };
-         unsigned char nulls[1000] = { 0 };
-
-         /* crypt piece by piece */
-         if ((err = rabbit_setup(&st, k, sizeof(k)))                          != CRYPT_OK) return err;
-         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt,       5, out))      != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt +  5, 29, out +  5)) != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34,  5, out + 34)) != CRYPT_OK) return err;
-         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1))   return CRYPT_FAIL_TESTVECTOR;
-
-      /* --- Test 4 (crypt in a single call) ------------------------------------ */
-
-         if ((err = rabbit_memory(k, sizeof(k), iv, sizeof(iv),
-                                   (unsigned char*)pt, sizeof(pt), out))      != CRYPT_OK) return err;
-         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV4", 1))   return CRYPT_FAIL_TESTVECTOR;
-         /* use 'out' (ciphertext) in the next decryption test */
-
-      /* --- Test 5 (decrypt ciphertext) ------------------------------------ */
-
-         /* decrypt ct (out) and compare with pt (start with only setiv() to reset) */
-         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
-         if ((err = rabbit_crypt(&st, out, ptlen, out2))                      != CRYPT_OK) return err;
-         if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV5", 1))  return CRYPT_FAIL_TESTVECTOR;
-
-      /* --- Test 6 (wipe state, incl key) ---------------------------------- */
-
-         if ((err = rabbit_done(&st))                      != CRYPT_OK) return err;
-         if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV6", 1))  return CRYPT_FAIL_TESTVECTOR;
-
-      }
-
-      return CRYPT_OK;
-   }
-#endif
-}
-
-/* -------------------------------------------------------------------------- */
-
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
diff --git a/src/stream/rabbit/rabbit_common.h b/src/stream/rabbit/rabbit_common.h
new file mode 100644
index 000000000..388ecb0a1
--- /dev/null
+++ b/src/stream/rabbit/rabbit_common.h
@@ -0,0 +1,154 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/******************************************************************************
+ * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
+ * and should run on any conforming C implementation (C90 or later).
+ *
+ * This implementation supports any key length up to 128 bits (16 bytes) and
+ * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
+ * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
+ * may be any length up to 8 bytes and will be padded out to 8 bytes.
+ *
+ * The eSTREAM submission was rather picky about the calling sequence of
+ * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
+ * calling ECRYPT_process_blocks() multiple times for a multiple of whole
+ * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
+ * were supported correctly.  This implementation handles the keystream
+ * differently and rabbit_crypt() may be called as many times as desired,
+ * crypting any number of bytes each time.
+ *
+ *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
+ *
+ * NB: One of the test vectors distributed by the eSTREAM site in the file
+ *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
+ *     in that ZIP file, the 3rd line in "out1" should be
+ *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
+ *
+ * Here is the original legal notice accompanying the Rabbit submission
+ * to the EU eSTREAM competition.
+ *---------------------------------------------------------------------------
+ * Copyright (C) Cryptico A/S. All rights reserved.
+ *
+ * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
+ *
+ * This software is developed by Cryptico A/S and/or its suppliers.
+ * All title and intellectual property rights in and to the software,
+ * including but not limited to patent rights and copyrights, are owned
+ * by Cryptico A/S and/or its suppliers.
+ *
+ * The software may be used solely for non-commercial purposes
+ * without the prior written consent of Cryptico A/S. For further
+ * information on licensing terms and conditions please contact
+ * Cryptico A/S at info@cryptico.com
+ *
+ * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
+ * are either trademarks or registered trademarks of Cryptico A/S.
+ *
+ * Cryptico A/S shall not in any way be liable for any use of this
+ * software. The software is provided "as is" without any express or
+ * implied warranty.
+ *---------------------------------------------------------------------------
+ * On October 6, 2008, Rabbit was "released into the public domain and
+ * may be used freely for any purpose."
+ *   http://www.ecrypt.eu.org/stream/rabbitpf.html
+ *   https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
+ ******************************************************************************/
+
+
+#ifdef LTC_RABBIT
+
+/* local/private prototypes  (NB: rabbit_ctx and rabbit_state are different)  */
+static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x);
+static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance);
+static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out);
+
+/* -------------------------------------------------------------------------- */
+
+/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
+/* the upper 32 bits XOR the lower 32 bits */
+static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x)
+{
+   ulong32 a, b, h, l;
+
+   /* Construct high and low argument for squaring */
+   a = x &  0xFFFF;
+   b = x >> 16;
+
+   /* Calculate high and low result of squaring */
+   h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b;
+   l = x * x;
+
+   /* Return high XOR low */
+   return (ulong32)(h^l);
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* Calculate the next internal state */
+static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance)
+{
+   ulong32 g[8], c_old[8], i;
+
+   /* Save old counter values */
+   for (i=0; i<8; i++) {
+      c_old[i] = p_instance->c[i];
+   }
+
+   /* Calculate new counter values */
+   p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry);
+   p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0]));
+   p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1]));
+   p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2]));
+   p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3]));
+   p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4]));
+   p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5]));
+   p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6]));
+   p_instance->carry = (p_instance->c[7] < c_old[7]);
+
+   /* Calculate the g-values */
+   for (i=0;i<8;i++) {
+      g[i] = _rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i]));
+   }
+
+   /* Calculate new state values */
+   p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16));
+   p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]);
+   p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16));
+   p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]);
+   p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16));
+   p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]);
+   p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16));
+   p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out)
+{
+    ulong32 *ptr;
+
+    /* Iterate the work context once */
+    _rabbit_next_state(&(st->work_ctx));
+
+    /* Generate 16 bytes of pseudo-random data */
+    ptr = (ulong32*)&(st->work_ctx.x);
+    STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0);
+    STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4);
+    STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8);
+    STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12);
+}
+
+/* -------------------------------------------------------------------------- */
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rabbit/rabbit_crypt.c b/src/stream/rabbit/rabbit_crypt.c
new file mode 100644
index 000000000..681b9984a
--- /dev/null
+++ b/src/stream/rabbit/rabbit_crypt.c
@@ -0,0 +1,118 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/******************************************************************************
+ * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
+ * and should run on any conforming C implementation (C90 or later).
+ *
+ * This implementation supports any key length up to 128 bits (16 bytes) and
+ * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
+ * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
+ * may be any length up to 8 bytes and will be padded out to 8 bytes.
+ *
+ * The eSTREAM submission was rather picky about the calling sequence of
+ * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
+ * calling ECRYPT_process_blocks() multiple times for a multiple of whole
+ * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
+ * were supported correctly.  This implementation handles the keystream
+ * differently and rabbit_crypt() may be called as many times as desired,
+ * crypting any number of bytes each time.
+ *
+ *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
+ *
+ * NB: One of the test vectors distributed by the eSTREAM site in the file
+ *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
+ *     in that ZIP file, the 3rd line in "out1" should be
+ *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
+ *
+ * Here is the original legal notice accompanying the Rabbit submission
+ * to the EU eSTREAM competition.
+ *---------------------------------------------------------------------------
+ * Copyright (C) Cryptico A/S. All rights reserved.
+ *
+ * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
+ *
+ * This software is developed by Cryptico A/S and/or its suppliers.
+ * All title and intellectual property rights in and to the software,
+ * including but not limited to patent rights and copyrights, are owned
+ * by Cryptico A/S and/or its suppliers.
+ *
+ * The software may be used solely for non-commercial purposes
+ * without the prior written consent of Cryptico A/S. For further
+ * information on licensing terms and conditions please contact
+ * Cryptico A/S at info@cryptico.com
+ *
+ * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
+ * are either trademarks or registered trademarks of Cryptico A/S.
+ *
+ * Cryptico A/S shall not in any way be liable for any use of this
+ * software. The software is provided "as is" without any express or
+ * implied warranty.
+ *---------------------------------------------------------------------------
+ * On October 6, 2008, Rabbit was "released into the public domain and
+ * may be used freely for any purpose."
+ *   http://www.ecrypt.eu.org/stream/rabbitpf.html
+ *   https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
+ ******************************************************************************/
+
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RABBIT
+
+#include "rabbit_common.h"
+
+/* ------------------------------------------------------------------------- */
+
+/* Crypt a chunk of any size (encrypt/decrypt) */
+int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out)
+{
+   unsigned char buf[16];
+   unsigned long i, j;
+
+   if (inlen == 0) return CRYPT_OK; /* nothing to do */
+
+   LTC_ARGCHK(st        != NULL);
+   LTC_ARGCHK(in        != NULL);
+   LTC_ARGCHK(out       != NULL);
+
+   if (st->unused > 0) {
+      j = MIN(st->unused, inlen);
+      for (i = 0; i < j; ++i, st->unused--) out[i] = in[i] ^ st->block[16 - st->unused];
+      inlen -= j;
+      if (inlen == 0) return CRYPT_OK;
+      out += j;
+      in  += j;
+   }
+   for (;;) {
+     /* gen a block for buf */
+     _rabbit_gen_1_block(st, buf);
+     if (inlen <= 16) {
+       /* XOR and send to out */
+       for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
+       st->unused = 16 - inlen;
+       /* copy remainder to block */
+       for (i = inlen; i < 16; ++i) st->block[i] = buf[i];
+       return CRYPT_OK;
+     }
+     /* XOR entire buf and send to out */
+     for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i];
+     inlen -= 16;
+     out += 16;
+     in  += 16;
+   }
+}
+
+/* -------------------------------------------------------------------------- */
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rabbit/rabbit_done.c b/src/stream/rabbit/rabbit_done.c
new file mode 100644
index 000000000..365925ab2
--- /dev/null
+++ b/src/stream/rabbit/rabbit_done.c
@@ -0,0 +1,85 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/******************************************************************************
+ * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
+ * and should run on any conforming C implementation (C90 or later).
+ *
+ * This implementation supports any key length up to 128 bits (16 bytes) and
+ * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
+ * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
+ * may be any length up to 8 bytes and will be padded out to 8 bytes.
+ *
+ * The eSTREAM submission was rather picky about the calling sequence of
+ * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
+ * calling ECRYPT_process_blocks() multiple times for a multiple of whole
+ * 16-byte blocks, but once ECRYPT_process_bytes() was called, no more calls
+ * were supported correctly.  This implementation handles the keystream
+ * differently and rabbit_crypt() may be called as many times as desired,
+ * crypting any number of bytes each time.
+ *
+ *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
+ *   https://www.ietf.org/rfc/rfc4503.txt
+ *
+ * NB: One of the test vectors distributed by the eSTREAM site in the file
+ *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
+ *     in that ZIP file, the 3rd line in "out1" should be
+ *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
+ *
+ *---------------------------------------------------------------------------
+ * Here is the original legal notice accompanying the Rabbit submission
+ * to the EU eSTREAM competition.
+ *
+ *   Copyright (C) Cryptico A/S. All rights reserved.
+ *
+ *   YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
+ *
+ *   This software is developed by Cryptico A/S and/or its suppliers.
+ *   All title and intellectual property rights in and to the software,
+ *   including but not limited to patent rights and copyrights, are owned
+ *   by Cryptico A/S and/or its suppliers.
+ *
+ *   The software may be used solely for non-commercial purposes
+ *   without the prior written consent of Cryptico A/S. For further
+ *   information on licensing terms and conditions please contact
+ *   Cryptico A/S at info@cryptico.com
+ *
+ *   Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
+ *   are either trademarks or registered trademarks of Cryptico A/S.
+ *
+ *   Cryptico A/S shall not in any way be liable for any use of this
+ *   software. The software is provided "as is" without any express or
+ *   implied warranty.
+ *
+ *---------------------------------------------------------------------------
+ * On October 6, 2008, Rabbit was "released into the public domain and
+ * may be used freely for any purpose."
+ *
+ *   http://www.ecrypt.eu.org/stream/rabbitpf.html
+ *
+ ******************************************************************************/
+
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RABBIT
+
+int rabbit_done(rabbit_state *st)
+{
+   LTC_ARGCHK(st != NULL);
+
+   zeromem(st, sizeof(rabbit_state));
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rabbit/rabbit_keystream.c b/src/stream/rabbit/rabbit_keystream.c
new file mode 100644
index 000000000..9c53d72a7
--- /dev/null
+++ b/src/stream/rabbit/rabbit_keystream.c
@@ -0,0 +1,87 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/******************************************************************************
+ * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
+ * and should run on any conforming C implementation (C90 or later).
+ *
+ * This implementation supports any key length up to 128 bits (16 bytes) and
+ * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
+ * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
+ * may be any length up to 8 bytes and will be padded out to 8 bytes.
+ *
+ * The eSTREAM submission was rather picky about the calling sequence of
+ * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
+ * calling ECRYPT_process_blocks() multiple times for a multiple of whole
+ * 16-byte blocks, but once ECRYPT_process_bytes() was called, no more calls
+ * were supported correctly.  This implementation handles the keystream
+ * differently and rabbit_crypt() may be called as many times as desired,
+ * crypting any number of bytes each time.
+ *
+ *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
+ *   https://www.ietf.org/rfc/rfc4503.txt
+ *
+ * NB: One of the test vectors distributed by the eSTREAM site in the file
+ *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
+ *     in that ZIP file, the 3rd line in "out1" should be
+ *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
+ *
+ *---------------------------------------------------------------------------
+ * Here is the original legal notice accompanying the Rabbit submission
+ * to the EU eSTREAM competition.
+ *
+ *   Copyright (C) Cryptico A/S. All rights reserved.
+ *
+ *   YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
+ *
+ *   This software is developed by Cryptico A/S and/or its suppliers.
+ *   All title and intellectual property rights in and to the software,
+ *   including but not limited to patent rights and copyrights, are owned
+ *   by Cryptico A/S and/or its suppliers.
+ *
+ *   The software may be used solely for non-commercial purposes
+ *   without the prior written consent of Cryptico A/S. For further
+ *   information on licensing terms and conditions please contact
+ *   Cryptico A/S at info@cryptico.com
+ *
+ *   Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
+ *   are either trademarks or registered trademarks of Cryptico A/S.
+ *
+ *   Cryptico A/S shall not in any way be liable for any use of this
+ *   software. The software is provided "as is" without any express or
+ *   implied warranty.
+ *
+ *---------------------------------------------------------------------------
+ * On October 6, 2008, Rabbit was "released into the public domain and
+ * may be used freely for any purpose."
+ *
+ *   http://www.ecrypt.eu.org/stream/rabbitpf.html
+ *
+ ******************************************************************************/
+
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RABBIT
+
+int rabbit_keystream(rabbit_state *st, unsigned char *out, unsigned long outlen)
+{
+   if (outlen == 0) return CRYPT_OK; /* nothing to do */
+
+   LTC_ARGCHK(out != NULL);
+
+   XMEMSET(out, 0, outlen);
+   return rabbit_crypt(st, out, outlen, out);
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rabbit/rabbit_setiv.c b/src/stream/rabbit/rabbit_setiv.c
new file mode 100644
index 000000000..c366126c1
--- /dev/null
+++ b/src/stream/rabbit/rabbit_setiv.c
@@ -0,0 +1,126 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/******************************************************************************
+ * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
+ * and should run on any conforming C implementation (C90 or later).
+ *
+ * This implementation supports any key length up to 128 bits (16 bytes) and
+ * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
+ * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
+ * may be any length up to 8 bytes and will be padded out to 8 bytes.
+ *
+ * The eSTREAM submission was rather picky about the calling sequence of
+ * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
+ * calling ECRYPT_process_blocks() multiple times for a multiple of whole
+ * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
+ * were supported correctly.  This implementation handles the keystream
+ * differently and rabbit_crypt() may be called as many times as desired,
+ * crypting any number of bytes each time.
+ *
+ *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
+ *
+ * NB: One of the test vectors distributed by the eSTREAM site in the file
+ *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
+ *     in that ZIP file, the 3rd line in "out1" should be
+ *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
+ *
+ * Here is the original legal notice accompanying the Rabbit submission
+ * to the EU eSTREAM competition.
+ *---------------------------------------------------------------------------
+ * Copyright (C) Cryptico A/S. All rights reserved.
+ *
+ * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
+ *
+ * This software is developed by Cryptico A/S and/or its suppliers.
+ * All title and intellectual property rights in and to the software,
+ * including but not limited to patent rights and copyrights, are owned
+ * by Cryptico A/S and/or its suppliers.
+ *
+ * The software may be used solely for non-commercial purposes
+ * without the prior written consent of Cryptico A/S. For further
+ * information on licensing terms and conditions please contact
+ * Cryptico A/S at info@cryptico.com
+ *
+ * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
+ * are either trademarks or registered trademarks of Cryptico A/S.
+ *
+ * Cryptico A/S shall not in any way be liable for any use of this
+ * software. The software is provided "as is" without any express or
+ * implied warranty.
+ *---------------------------------------------------------------------------
+ * On October 6, 2008, Rabbit was "released into the public domain and
+ * may be used freely for any purpose."
+ *   http://www.ecrypt.eu.org/stream/rabbitpf.html
+ *   https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
+ ******************************************************************************/
+
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RABBIT
+
+#include "rabbit_common.h"
+
+/* -------------------------------------------------------------------------- */
+
+/* IV setup */
+int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen)
+{
+   ulong32 i0, i1, i2, i3, i;
+   unsigned char  tmpiv[8] = {0};
+
+   LTC_ARGCHK(st != NULL);
+   LTC_ARGCHK(iv != NULL || ivlen == 0);
+   LTC_ARGCHK(ivlen <= 8);
+
+   /* pad iv in tmpiv */
+   if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen);
+
+   /* Generate four subvectors */
+   LOAD32L(i0, tmpiv+0);
+   LOAD32L(i2, tmpiv+4);
+   i1 = (i0>>16) | (i2&0xFFFF0000);
+   i3 = (i2<<16) | (i0&0x0000FFFF);
+
+   /* Modify counter values */
+   st->work_ctx.c[0] = st->master_ctx.c[0] ^ i0;
+   st->work_ctx.c[1] = st->master_ctx.c[1] ^ i1;
+   st->work_ctx.c[2] = st->master_ctx.c[2] ^ i2;
+   st->work_ctx.c[3] = st->master_ctx.c[3] ^ i3;
+   st->work_ctx.c[4] = st->master_ctx.c[4] ^ i0;
+   st->work_ctx.c[5] = st->master_ctx.c[5] ^ i1;
+   st->work_ctx.c[6] = st->master_ctx.c[6] ^ i2;
+   st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3;
+
+   /* Copy state variables */
+   for (i=0; i<8; i++) {
+      st->work_ctx.x[i] = st->master_ctx.x[i];
+   }
+   st->work_ctx.carry = st->master_ctx.carry;
+
+   /* Iterate the work context four times */
+   for (i=0; i<4; i++) {
+      _rabbit_next_state(&(st->work_ctx));
+   }
+
+   /* reset keystream buffer and unused count */
+   XMEMSET(&(st->block), 0, sizeof(st->block));
+   st->unused = 0;
+
+   return CRYPT_OK;
+}
+
+/* ------------------------------------------------------------------------- */
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rabbit/rabbit_setup.c b/src/stream/rabbit/rabbit_setup.c
new file mode 100644
index 000000000..72a9f07d3
--- /dev/null
+++ b/src/stream/rabbit/rabbit_setup.c
@@ -0,0 +1,152 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/******************************************************************************
+ * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
+ * and should run on any conforming C implementation (C90 or later).
+ *
+ * This implementation supports any key length up to 128 bits (16 bytes) and
+ * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
+ * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
+ * may be any length up to 8 bytes and will be padded out to 8 bytes.
+ *
+ * The eSTREAM submission was rather picky about the calling sequence of
+ * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
+ * calling ECRYPT_process_blocks() multiple times for a multiple of whole
+ * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
+ * were supported correctly.  This implementation handles the keystream
+ * differently and rabbit_crypt() may be called as many times as desired,
+ * crypting any number of bytes each time.
+ *
+ *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
+ *
+ * NB: One of the test vectors distributed by the eSTREAM site in the file
+ *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
+ *     in that ZIP file, the 3rd line in "out1" should be
+ *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
+ *
+ * Here is the original legal notice accompanying the Rabbit submission
+ * to the EU eSTREAM competition.
+ *---------------------------------------------------------------------------
+ * Copyright (C) Cryptico A/S. All rights reserved.
+ *
+ * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
+ *
+ * This software is developed by Cryptico A/S and/or its suppliers.
+ * All title and intellectual property rights in and to the software,
+ * including but not limited to patent rights and copyrights, are owned
+ * by Cryptico A/S and/or its suppliers.
+ *
+ * The software may be used solely for non-commercial purposes
+ * without the prior written consent of Cryptico A/S. For further
+ * information on licensing terms and conditions please contact
+ * Cryptico A/S at info@cryptico.com
+ *
+ * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
+ * are either trademarks or registered trademarks of Cryptico A/S.
+ *
+ * Cryptico A/S shall not in any way be liable for any use of this
+ * software. The software is provided "as is" without any express or
+ * implied warranty.
+ *---------------------------------------------------------------------------
+ * On October 6, 2008, Rabbit was "released into the public domain and
+ * may be used freely for any purpose."
+ *   http://www.ecrypt.eu.org/stream/rabbitpf.html
+ *   https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
+ ******************************************************************************/
+
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RABBIT
+
+#include "rabbit_common.h"
+
+/* -------------------------------------------------------------------------- */
+
+/* Key setup */
+int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen)
+{
+   ulong32 k0, k1, k2, k3, i;
+   unsigned char  tmpkey[16] = {0};
+
+   LTC_ARGCHK(st != NULL);
+   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(keylen <= 16);
+
+   /* init state */
+   XMEMSET(st, 0, sizeof(rabbit_state));
+
+   /* pad key in tmpkey */
+   XMEMCPY(tmpkey, key, keylen);
+
+   /* Generate four subkeys */
+   LOAD32L(k0, tmpkey+ 0);
+   LOAD32L(k1, tmpkey+ 4);
+   LOAD32L(k2, tmpkey+ 8);
+   LOAD32L(k3, tmpkey+12);
+
+#ifdef LTC_CLEAN_STACK
+   /* done with tmpkey, wipe it */
+   zeromem(tmpkey, sizeof(tmpkey));
+#endif
+
+   /* Generate initial state variables */
+   st->master_ctx.x[0] = k0;
+   st->master_ctx.x[2] = k1;
+   st->master_ctx.x[4] = k2;
+   st->master_ctx.x[6] = k3;
+   st->master_ctx.x[1] = (ulong32)(k3<<16) | (k2>>16);
+   st->master_ctx.x[3] = (ulong32)(k0<<16) | (k3>>16);
+   st->master_ctx.x[5] = (ulong32)(k1<<16) | (k0>>16);
+   st->master_ctx.x[7] = (ulong32)(k2<<16) | (k1>>16);
+
+   /* Generate initial counter values */
+   st->master_ctx.c[0] = ROLc(k2, 16);
+   st->master_ctx.c[2] = ROLc(k3, 16);
+   st->master_ctx.c[4] = ROLc(k0, 16);
+   st->master_ctx.c[6] = ROLc(k1, 16);
+   st->master_ctx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
+   st->master_ctx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
+   st->master_ctx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
+   st->master_ctx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
+
+   /* Clear carry bit */
+   st->master_ctx.carry = 0;
+
+   /* Iterate the master context four times */
+   for (i=0; i<4; i++) {
+      _rabbit_next_state(&(st->master_ctx));
+   }
+
+   /* Modify the counters */
+   for (i=0; i<8; i++) {
+      st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7];
+   }
+
+   /* Copy master instance to work instance */
+   for (i=0; i<8; i++) {
+      st->work_ctx.x[i] = st->master_ctx.x[i];
+      st->work_ctx.c[i] = st->master_ctx.c[i];
+   }
+   st->work_ctx.carry = st->master_ctx.carry;
+   /* ...and prepare block for crypt() */
+   XMEMSET(&(st->block), 0, sizeof(st->block));
+   st->unused = 0;
+
+   return CRYPT_OK;
+}
+
+/* -------------------------------------------------------------------------- */
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rabbit/rabbit_test.c b/src/stream/rabbit/rabbit_test.c
new file mode 100644
index 000000000..098c66971
--- /dev/null
+++ b/src/stream/rabbit/rabbit_test.c
@@ -0,0 +1,191 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/******************************************************************************
+ * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
+ * and should run on any conforming C implementation (C90 or later).
+ *
+ * This implementation supports any key length up to 128 bits (16 bytes) and
+ * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
+ * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
+ * may be any length up to 8 bytes and will be padded out to 8 bytes.
+ *
+ * The eSTREAM submission was rather picky about the calling sequence of
+ * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
+ * calling ECRYPT_process_blocks() multiple times for a multiple of whole
+ * 16-byte blocks, but once ECRYPT_process_bytes() was called, no more calls
+ * were supported correctly.  This implementation handles the keystream
+ * differently and rabbit_crypt() may be called as many times as desired,
+ * crypting any number of bytes each time.
+ *
+ *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
+ *   https://www.ietf.org/rfc/rfc4503.txt
+ *
+ * NB: One of the test vectors distributed by the eSTREAM site in the file
+ *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
+ *     in that ZIP file, the 3rd line in "out1" should be
+ *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
+ *
+ *---------------------------------------------------------------------------
+ * Here is the original legal notice accompanying the Rabbit submission
+ * to the EU eSTREAM competition.
+ *
+ *   Copyright (C) Cryptico A/S. All rights reserved.
+ *
+ *   YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
+ *
+ *   This software is developed by Cryptico A/S and/or its suppliers.
+ *   All title and intellectual property rights in and to the software,
+ *   including but not limited to patent rights and copyrights, are owned
+ *   by Cryptico A/S and/or its suppliers.
+ *
+ *   The software may be used solely for non-commercial purposes
+ *   without the prior written consent of Cryptico A/S. For further
+ *   information on licensing terms and conditions please contact
+ *   Cryptico A/S at info@cryptico.com
+ *
+ *   Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
+ *   are either trademarks or registered trademarks of Cryptico A/S.
+ *
+ *   Cryptico A/S shall not in any way be liable for any use of this
+ *   software. The software is provided "as is" without any express or
+ *   implied warranty.
+ *
+ *---------------------------------------------------------------------------
+ * On October 6, 2008, Rabbit was "released into the public domain and
+ * may be used freely for any purpose."
+ *
+ *   http://www.ecrypt.eu.org/stream/rabbitpf.html
+ *
+ ******************************************************************************/
+
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RABBIT
+
+int rabbit_test(void)
+{
+#ifndef LTC_TEST
+   return CRYPT_NOP;
+#else
+   rabbit_state st;
+   int err;
+   unsigned char out[1000] = { 0 };
+   {
+      /* all 3 tests use key and iv fm set 6, vector 3, the last vector in:
+         http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/rabbit/verified.test-vectors?rev=210&view=log
+      */
+
+      /* --- Test 1 (generate whole blocks) --------------------------------- */
+
+      {
+         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
+                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
+         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
+         char pt[64]        = { 0 };
+         unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
+                                0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
+                                0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
+                                0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
+                                0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D, 0x7C,
+                                0x0C, 0x10, 0x9B, 0x79, 0xD5, 0x74, 0x94, 0x39,
+                                0xB7, 0xEF, 0xA4, 0xC4, 0xC9, 0xC8, 0xD2, 0x9D,
+                                0xC5, 0xB3, 0x88, 0x83, 0x14, 0xA6, 0x81, 0x6F };
+         unsigned long ptlen = sizeof(pt);
+
+         /* crypt 64 nulls */
+         if ((err = rabbit_setup(&st, k, sizeof(k)))                   != CRYPT_OK) return err;
+         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                 != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt, ptlen, out)) != CRYPT_OK) return err;
+         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV1", 1))   return CRYPT_FAIL_TESTVECTOR;
+      }
+
+      /* --- Test 2 (generate unusual number of bytes each time) ------------ */
+
+      {
+         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
+                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
+         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
+         char          pt[39] = { 0 };
+         unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA,   0x96, 0xAF, 0xF6, 0xCA,
+                                0xCF, 0x2A, 0x45, 0x9A,   0x10, 0x2A, 0x7F, 0x78,
+                                0xCA, 0x98, 0x5C, 0xF8,   0xFD, 0xD1, 0x47, 0x40,
+                                0x18, 0x75, 0x8E, 0x36,   0xAE, 0x99, 0x23, 0xF5,
+                                0x19, 0xD1, 0x3D, 0x71,   0x8D, 0xAF, 0x8D };
+         unsigned long ptlen = sizeof(pt);
+
+         /* crypt piece by piece (hit at least one 16-byte boundary) */
+         if ((err = rabbit_setup(&st, k, sizeof(k)))                          != CRYPT_OK) return err;
+         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt,       5, out))      != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt +  5, 11, out +  5)) != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 16, 14, out + 16)) != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 30,  2, out + 30)) != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 32,  7, out + 32)) != CRYPT_OK) return err;
+         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV2", 1))   return CRYPT_FAIL_TESTVECTOR;
+      }
+
+      /* --- Test 3 (use non-null data) ------------------------------------- */
+
+      {
+         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
+                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
+         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
+         char          pt[] = "Kilroy was here, there, and everywhere!";
+         unsigned char ct[] = { 0x2a, 0x55, 0xdc, 0xc8,   0xf9, 0xd6, 0xd6, 0xbd,
+                                0xae, 0x59, 0x65, 0xf2,   0x75, 0x58, 0x1a, 0x54,
+                                0xea, 0xec, 0x34, 0x9d,   0x8f, 0xb4, 0x6b, 0x60,
+                                0x79, 0x1b, 0xea, 0x16,   0xcb, 0xef, 0x46, 0x87,
+                                0x60, 0xa6, 0x55, 0x14,   0xff, 0xca, 0xac };
+         unsigned long ptlen = strlen(pt);
+         unsigned char out2[1000] = { 0 };
+         unsigned char nulls[1000] = { 0 };
+
+         /* crypt piece by piece */
+         if ((err = rabbit_setup(&st, k, sizeof(k)))                          != CRYPT_OK) return err;
+         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt,       5, out))      != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt +  5, 29, out +  5)) != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34,  5, out + 34)) != CRYPT_OK) return err;
+         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1))   return CRYPT_FAIL_TESTVECTOR;
+
+      /* --- Test 4 (crypt in a single call) ------------------------------------ */
+
+         if ((err = rabbit_memory(k, sizeof(k), iv, sizeof(iv),
+                                   (unsigned char*)pt, sizeof(pt), out))      != CRYPT_OK) return err;
+         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV4", 1))   return CRYPT_FAIL_TESTVECTOR;
+         /* use 'out' (ciphertext) in the next decryption test */
+
+      /* --- Test 5 (decrypt ciphertext) ------------------------------------ */
+
+         /* decrypt ct (out) and compare with pt (start with only setiv() to reset) */
+         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
+         if ((err = rabbit_crypt(&st, out, ptlen, out2))                      != CRYPT_OK) return err;
+         if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV5", 1))  return CRYPT_FAIL_TESTVECTOR;
+
+      /* --- Test 6 (wipe state, incl key) ---------------------------------- */
+
+         if ((err = rabbit_done(&st))                      != CRYPT_OK) return err;
+         if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV6", 1))  return CRYPT_FAIL_TESTVECTOR;
+
+      }
+
+      return CRYPT_OK;
+   }
+#endif
+}
+
+/* -------------------------------------------------------------------------- */
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rc4/rc4_stream.c b/src/stream/rc4/rc4_stream.c
deleted file mode 100644
index f1c225d01..000000000
--- a/src/stream/rc4/rc4_stream.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- */
-
-#include "tomcrypt_private.h"
-
-#ifdef LTC_RC4_STREAM
-
-/**
-   Initialize an RC4 context (only the key)
-   @param st        [out] The destination of the RC4 state
-   @param key       The secret key
-   @param keylen    The length of the secret key (8 - 256 bytes)
-   @return CRYPT_OK if successful
-*/
-int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
-{
-   unsigned char tmp, *s;
-   int x, y;
-   unsigned long j;
-
-   LTC_ARGCHK(st  != NULL);
-   LTC_ARGCHK(key != NULL);
-   LTC_ARGCHK(keylen >= 5); /* 40-2048 bits */
-
-   s = st->buf;
-   for (x = 0; x < 256; x++) {
-      s[x] = x;
-   }
-
-   for (j = x = y = 0; x < 256; x++) {
-      y = (y + s[x] + key[j++]) & 255;
-      if (j == keylen) {
-         j = 0;
-      }
-      tmp = s[x]; s[x] = s[y]; s[y] = tmp;
-   }
-   st->x = 0;
-   st->y = 0;
-
-   return CRYPT_OK;
-}
-
-/**
-   Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4
-   @param st      The RC4 state
-   @param in      The plaintext (or ciphertext)
-   @param inlen   The length of the input (octets)
-   @param out     [out] The ciphertext (or plaintext), length inlen
-   @return CRYPT_OK if successful
-*/
-int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
-{
-   unsigned char x, y, *s, tmp;
-
-   LTC_ARGCHK(st  != NULL);
-   LTC_ARGCHK(in  != NULL);
-   LTC_ARGCHK(out != NULL);
-
-   x = st->x;
-   y = st->y;
-   s = st->buf;
-   while (inlen--) {
-      x = (x + 1) & 255;
-      y = (y + s[x]) & 255;
-      tmp = s[x]; s[x] = s[y]; s[y] = tmp;
-      tmp = (s[x] + s[y]) & 255;
-      *out++ = *in++ ^ s[tmp];
-   }
-   st->x = x;
-   st->y = y;
-   return CRYPT_OK;
-}
-
-/**
-  Generate a stream of random bytes via RC4
-  @param st      The RC420 state
-  @param out     [out] The output buffer
-  @param outlen  The output length
-  @return CRYPT_OK on success
- */
-int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen)
-{
-   if (outlen == 0) return CRYPT_OK; /* nothing to do */
-   LTC_ARGCHK(out != NULL);
-   XMEMSET(out, 0, outlen);
-   return rc4_stream_crypt(st, out, outlen, out);
-}
-
-/**
-  Terminate and clear RC4 state
-  @param st      The RC4 state
-  @return CRYPT_OK on success
-*/
-int rc4_stream_done(rc4_state *st)
-{
-   LTC_ARGCHK(st != NULL);
-   XMEMSET(st, 0, sizeof(rc4_state));
-   return CRYPT_OK;
-}
-
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
diff --git a/src/stream/rc4/rc4_stream_crypt.c b/src/stream/rc4/rc4_stream_crypt.c
new file mode 100644
index 000000000..0170f63a2
--- /dev/null
+++ b/src/stream/rc4/rc4_stream_crypt.c
@@ -0,0 +1,49 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RC4_STREAM
+
+/**
+   Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4
+   @param st      The RC4 state
+   @param in      The plaintext (or ciphertext)
+   @param inlen   The length of the input (octets)
+   @param out     [out] The ciphertext (or plaintext), length inlen
+   @return CRYPT_OK if successful
+*/
+int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
+{
+   unsigned char x, y, *s, tmp;
+
+   LTC_ARGCHK(st  != NULL);
+   LTC_ARGCHK(in  != NULL);
+   LTC_ARGCHK(out != NULL);
+
+   x = st->x;
+   y = st->y;
+   s = st->buf;
+   while (inlen--) {
+      x = (x + 1) & 255;
+      y = (y + s[x]) & 255;
+      tmp = s[x]; s[x] = s[y]; s[y] = tmp;
+      tmp = (s[x] + s[y]) & 255;
+      *out++ = *in++ ^ s[tmp];
+   }
+   st->x = x;
+   st->y = y;
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rc4/rc4_stream_done.c b/src/stream/rc4/rc4_stream_done.c
new file mode 100644
index 000000000..e0d5c30d8
--- /dev/null
+++ b/src/stream/rc4/rc4_stream_done.c
@@ -0,0 +1,31 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RC4_STREAM
+
+
+/**
+  Terminate and clear RC4 state
+  @param st      The RC4 state
+  @return CRYPT_OK on success
+*/
+int rc4_stream_done(rc4_state *st)
+{
+   LTC_ARGCHK(st != NULL);
+   XMEMSET(st, 0, sizeof(rc4_state));
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rc4/rc4_stream_keystream.c b/src/stream/rc4/rc4_stream_keystream.c
new file mode 100644
index 000000000..e1ad78585
--- /dev/null
+++ b/src/stream/rc4/rc4_stream_keystream.c
@@ -0,0 +1,34 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RC4_STREAM
+
+
+/**
+  Generate a stream of random bytes via RC4
+  @param st      The RC420 state
+  @param out     [out] The output buffer
+  @param outlen  The output length
+  @return CRYPT_OK on success
+ */
+int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen)
+{
+   if (outlen == 0) return CRYPT_OK; /* nothing to do */
+   LTC_ARGCHK(out != NULL);
+   XMEMSET(out, 0, outlen);
+   return rc4_stream_crypt(st, out, outlen, out);
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/rc4/rc4_stream_setup.c b/src/stream/rc4/rc4_stream_setup.c
new file mode 100644
index 000000000..0e0aafdab
--- /dev/null
+++ b/src/stream/rc4/rc4_stream_setup.c
@@ -0,0 +1,53 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_RC4_STREAM
+
+/**
+   Initialize an RC4 context (only the key)
+   @param st        [out] The destination of the RC4 state
+   @param key       The secret key
+   @param keylen    The length of the secret key (8 - 256 bytes)
+   @return CRYPT_OK if successful
+*/
+int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
+{
+   unsigned char tmp, *s;
+   int x, y;
+   unsigned long j;
+
+   LTC_ARGCHK(st  != NULL);
+   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(keylen >= 5); /* 40-2048 bits */
+
+   s = st->buf;
+   for (x = 0; x < 256; x++) {
+      s[x] = x;
+   }
+
+   for (j = x = y = 0; x < 256; x++) {
+      y = (y + s[x] + key[j++]) & 255;
+      if (j == keylen) {
+         j = 0;
+      }
+      tmp = s[x]; s[x] = s[y]; s[y] = tmp;
+   }
+   st->x = 0;
+   st->y = 0;
+
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sober128/sober128_stream.c b/src/stream/sober128/sober128_stream.c
deleted file mode 100644
index 952d5622e..000000000
--- a/src/stream/sober128/sober128_stream.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- */
-#include "tomcrypt_private.h"
-
-/**
- @file sober128_stream.c
- Implementation of SOBER-128 by Tom St Denis.
- Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
-*/
-
-#ifdef LTC_SOBER128
-
-#define __LTC_SOBER128TAB_C__
-#include "sober128tab.c"
-
-/* don't change these... */
-#define N                        17
-#define INITKONST        0x6996c53a /* value of KONST to use during key loading */
-#define KEYP                     15 /* where to insert key words */
-#define FOLDP                     4 /* where to insert non-linear feedback */
-
-static ulong32 BYTE2WORD(const unsigned char *b)
-{
-   ulong32 t;
-   LOAD32L(t, b);
-   return t;
-}
-
-static void XORWORD(ulong32 w, const unsigned char *in, unsigned char *out)
-{
-   ulong32 t;
-   LOAD32L(t, in);
-   t ^= w;
-   STORE32L(t, out);
-}
-
-/* give correct offset for the current position of the register,
- * where logically R[0] is at position "zero".
- */
-#define OFF(zero, i) (((zero)+(i)) % N)
-
-/* step the LFSR */
-/* After stepping, "zero" moves right one place */
-#define STEP(R,z) \
-    R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
-
-static void cycle(ulong32 *R)
-{
-    ulong32 t;
-    int     i;
-
-    STEP(R,0);
-    t = R[0];
-    for (i = 1; i < N; ++i) {
-        R[i-1] = R[i];
-    }
-    R[N-1] = t;
-}
-
-/* Return a non-linear function of some parts of the register.
- */
-#define NLFUNC(st,z) \
-{ \
-    t = st->R[OFF(z,0)] + st->R[OFF(z,16)]; \
-    t ^= Sbox[(t >> 24) & 0xFF]; \
-    t = RORc(t, 8); \
-    t = ((t + st->R[OFF(z,1)]) ^ st->konst) + st->R[OFF(z,6)]; \
-    t ^= Sbox[(t >> 24) & 0xFF]; \
-    t = t + st->R[OFF(z,13)]; \
-}
-
-static ulong32 nltap(const sober128_state *st)
-{
-    ulong32 t;
-    NLFUNC(st, 0);
-    return t;
-}
-
-/* Save the current register state
- */
-static void s128_savestate(sober128_state *st)
-{
-    int i;
-    for (i = 0; i < N; ++i) {
-        st->initR[i] = st->R[i];
-    }
-}
-
-/* initialise to previously saved register state
- */
-static void s128_reloadstate(sober128_state *st)
-{
-    int i;
-
-    for (i = 0; i < N; ++i) {
-        st->R[i] = st->initR[i];
-    }
-}
-
-/* Initialise "konst"
- */
-static void s128_genkonst(sober128_state *st)
-{
-    ulong32 newkonst;
-
-    do {
-       cycle(st->R);
-       newkonst = nltap(st);
-    } while ((newkonst & 0xFF000000) == 0);
-    st->konst = newkonst;
-}
-
-/* Load key material into the register
- */
-#define ADDKEY(k) \
-   st->R[KEYP] += (k);
-
-#define XORNL(nl) \
-   st->R[FOLDP] ^= (nl);
-
-/* nonlinear diffusion of register for key */
-#define DROUND(z) STEP(st->R,z); NLFUNC(st,(z+1)); st->R[OFF((z+1),FOLDP)] ^= t;
-static void s128_diffuse(sober128_state *st)
-{
-    ulong32 t;
-    /* relies on FOLD == N == 17! */
-    DROUND(0);
-    DROUND(1);
-    DROUND(2);
-    DROUND(3);
-    DROUND(4);
-    DROUND(5);
-    DROUND(6);
-    DROUND(7);
-    DROUND(8);
-    DROUND(9);
-    DROUND(10);
-    DROUND(11);
-    DROUND(12);
-    DROUND(13);
-    DROUND(14);
-    DROUND(15);
-    DROUND(16);
-}
-
-/**
-   Initialize an Sober128 context (only the key)
-   @param st        [out] The destination of the Sober128 state
-   @param key       The secret key
-   @param keylen    The length of the secret key (octets)
-   @return CRYPT_OK if successful
-*/
-int sober128_stream_setup(sober128_state *st, const unsigned char *key, unsigned long keylen)
-{
-   ulong32 i, k;
-
-   LTC_ARGCHK(st  != NULL);
-   LTC_ARGCHK(key != NULL);
-   LTC_ARGCHK(keylen > 0);
-
-   /* keylen must be multiple of 4 bytes */
-   if ((keylen & 3) != 0) {
-      return CRYPT_INVALID_KEYSIZE;
-   }
-
-   /* Register initialised to Fibonacci numbers */
-   st->R[0] = 1;
-   st->R[1] = 1;
-   for (i = 2; i < N; ++i) {
-      st->R[i] = st->R[i-1] + st->R[i-2];
-   }
-   st->konst = INITKONST;
-
-   for (i = 0; i < keylen; i += 4) {
-      k = BYTE2WORD((unsigned char *)&key[i]);
-      ADDKEY(k);
-      cycle(st->R);
-      XORNL(nltap(st));
-   }
-
-   /* also fold in the length of the key */
-   ADDKEY(keylen);
-
-   /* now diffuse */
-   s128_diffuse(st);
-   s128_genkonst(st);
-   s128_savestate(st);
-   st->nbuf = 0;
-
-   return CRYPT_OK;
-}
-
-/**
-  Set IV to the Sober128 state
-  @param st      The Sober12820 state
-  @param iv      The IV data to add
-  @param ivlen   The length of the IV (must be 12)
-  @return CRYPT_OK on success
- */
-int sober128_stream_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen)
-{
-   ulong32 i, k;
-
-   LTC_ARGCHK(st != NULL);
-   LTC_ARGCHK(iv != NULL);
-   LTC_ARGCHK(ivlen > 0);
-
-   /* ok we are adding an IV then... */
-   s128_reloadstate(st);
-
-   /* ivlen must be multiple of 4 bytes */
-   if ((ivlen & 3) != 0) {
-      return CRYPT_INVALID_KEYSIZE;
-   }
-
-   for (i = 0; i < ivlen; i += 4) {
-      k = BYTE2WORD((unsigned char *)&iv[i]);
-      ADDKEY(k);
-      cycle(st->R);
-      XORNL(nltap(st));
-   }
-
-   /* also fold in the length of the key */
-   ADDKEY(ivlen);
-
-   /* now diffuse */
-   s128_diffuse(st);
-   st->nbuf = 0;
-
-   return CRYPT_OK;
-}
-
-/* XOR pseudo-random bytes into buffer
- */
-#define SROUND(z) STEP(st->R,z); NLFUNC(st,(z+1)); XORWORD(t, in+(z*4), out+(z*4));
-
-/**
-   Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128
-   @param st      The Sober128 state
-   @param in      The plaintext (or ciphertext)
-   @param inlen   The length of the input (octets)
-   @param out     [out] The ciphertext (or plaintext), length inlen
-   @return CRYPT_OK if successful
-*/
-int sober128_stream_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
-{
-   ulong32 t;
-
-   if (inlen == 0) return CRYPT_OK; /* nothing to do */
-   LTC_ARGCHK(out != NULL);
-   LTC_ARGCHK(st  != NULL);
-
-   /* handle any previously buffered bytes */
-   while (st->nbuf != 0 && inlen != 0) {
-      *out++ = *in++ ^ (unsigned char)(st->sbuf & 0xFF);
-      st->sbuf >>= 8;
-      st->nbuf -= 8;
-      --inlen;
-   }
-
-#ifndef LTC_SMALL_CODE
-   /* do lots at a time, if there's enough to do */
-   while (inlen >= N*4) {
-      SROUND(0);
-      SROUND(1);
-      SROUND(2);
-      SROUND(3);
-      SROUND(4);
-      SROUND(5);
-      SROUND(6);
-      SROUND(7);
-      SROUND(8);
-      SROUND(9);
-      SROUND(10);
-      SROUND(11);
-      SROUND(12);
-      SROUND(13);
-      SROUND(14);
-      SROUND(15);
-      SROUND(16);
-      out    += 4*N;
-      in     += 4*N;
-      inlen  -= 4*N;
-   }
-#endif
-
-   /* do small or odd size buffers the slow way */
-   while (4 <= inlen) {
-      cycle(st->R);
-      t = nltap(st);
-      XORWORD(t, in, out);
-      out    += 4;
-      in     += 4;
-      inlen  -= 4;
-   }
-
-   /* handle any trailing bytes */
-   if (inlen != 0) {
-      cycle(st->R);
-      st->sbuf = nltap(st);
-      st->nbuf = 32;
-      while (st->nbuf != 0 && inlen != 0) {
-          *out++ = *in++ ^ (unsigned char)(st->sbuf & 0xFF);
-          st->sbuf >>= 8;
-          st->nbuf -= 8;
-          --inlen;
-      }
-   }
-
-   return CRYPT_OK;
-}
-
-int sober128_stream_keystream(sober128_state *st, unsigned char *out, unsigned long outlen)
-{
-   if (outlen == 0) return CRYPT_OK; /* nothing to do */
-   LTC_ARGCHK(out != NULL);
-   XMEMSET(out, 0, outlen);
-   return sober128_stream_crypt(st, out, outlen, out);
-}
-
-/**
-  Terminate and clear Sober128 state
-  @param st      The Sober128 state
-  @return CRYPT_OK on success
-*/
-int sober128_stream_done(sober128_state *st)
-{
-   LTC_ARGCHK(st != NULL);
-   XMEMSET(st, 0, sizeof(sober128_state));
-   return CRYPT_OK;
-}
-
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
diff --git a/src/stream/sober128/sober128_stream_common.h b/src/stream/sober128/sober128_stream_common.h
new file mode 100644
index 000000000..fcfeaa7a1
--- /dev/null
+++ b/src/stream/sober128/sober128_stream_common.h
@@ -0,0 +1,123 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+
+/**
+ @file sober128_stream.c
+ Implementation of SOBER-128 by Tom St Denis.
+ Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
+*/
+
+#ifdef LTC_SOBER128
+
+
+#if defined(LTC_SOBER128_STREAM_SETUP) || defined(LTC_SOBER128_STREAM_SETIV)
+
+/* local prototypes */
+static void _s128_diffuse(sober128_state *st);
+
+#endif  /* LTC_SOBER128_STREAM_SETUP || LTC_SOBER128_STREAM_SETIV */
+
+
+/* don't change these... */
+#define N                        17
+#define INITKONST        0x6996c53a /* value of KONST to use during key loading */
+#define KEYP                     15 /* where to insert key words */
+#define FOLDP                     4 /* where to insert non-linear feedback */
+
+
+/* give correct offset for the current position of the register,
+ * where logically R[0] is at position "zero".
+ */
+#define OFF(zero, i) (((zero)+(i)) % N)
+
+/* step the LFSR */
+/* After stepping, "zero" moves right one place */
+#define STEP(R,z) \
+    R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
+
+static void _cycle(ulong32 *R)
+{
+    ulong32 t;
+    int     i;
+
+    STEP(R,0);
+    t = R[0];
+    for (i = 1; i < N; ++i) {
+        R[i-1] = R[i];
+    }
+    R[N-1] = t;
+}
+
+/* Return a non-linear function of some parts of the register.
+ */
+#define NLFUNC(st,z) \
+{ \
+    t = st->R[OFF(z,0)] + st->R[OFF(z,16)]; \
+    t ^= Sbox[(t >> 24) & 0xFF]; \
+    t = RORc(t, 8); \
+    t = ((t + st->R[OFF(z,1)]) ^ st->konst) + st->R[OFF(z,6)]; \
+    t ^= Sbox[(t >> 24) & 0xFF]; \
+    t = t + st->R[OFF(z,13)]; \
+}
+
+static ulong32 _nltap(const sober128_state *st)
+{
+    ulong32 t;
+    NLFUNC(st, 0);
+    return t;
+}
+
+
+/* Load key material into the register
+ */
+#define ADDKEY(k) \
+   st->R[KEYP] += (k);
+
+#define XORNL(nl) \
+   st->R[FOLDP] ^= (nl);
+
+
+#if defined(LTC_SOBER128_STREAM_SETUP) || defined(LTC_SOBER128_STREAM_SETIV)
+
+/* nonlinear diffusion of register for key */
+#define DROUND(z) STEP(st->R,z); NLFUNC(st,(z+1)); st->R[OFF((z+1),FOLDP)] ^= t;
+
+/* _s128_diffuse() used in sober128_stream_setup() and sober128_stream_setiv() */
+static void _s128_diffuse(sober128_state *st)
+{
+    ulong32 t;
+    /* relies on FOLD == N == 17! */
+    DROUND(0);
+    DROUND(1);
+    DROUND(2);
+    DROUND(3);
+    DROUND(4);
+    DROUND(5);
+    DROUND(6);
+    DROUND(7);
+    DROUND(8);
+    DROUND(9);
+    DROUND(10);
+    DROUND(11);
+    DROUND(12);
+    DROUND(13);
+    DROUND(14);
+    DROUND(15);
+    DROUND(16);
+}
+
+#endif  /* LTC_SOBER128_STREAM_SETUP || LTC_SOBER128_STREAM_SETIV */
+
+
+#endif  /* LTC_SOBER128 */
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sober128/sober128_stream_crypt.c b/src/stream/sober128/sober128_stream_crypt.c
new file mode 100644
index 000000000..9ba6a8742
--- /dev/null
+++ b/src/stream/sober128/sober128_stream_crypt.c
@@ -0,0 +1,119 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+ @file sober128_stream.c
+ Implementation of SOBER-128 by Tom St Denis.
+ Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
+*/
+
+#ifdef LTC_SOBER128
+
+#define __LTC_SOBER128TAB_C__
+#include "sober128tab.c"
+
+#include "sober128_stream_common.h"
+
+
+static void _xorword(ulong32 w, const unsigned char *in, unsigned char *out)
+{
+   ulong32 t;
+   LOAD32L(t, in);
+   t ^= w;
+   STORE32L(t, out);
+}
+
+
+/* XOR pseudo-random bytes into buffer
+ */
+#define SROUND(z) STEP(st->R,z); NLFUNC(st,(z+1)); _xorword(t, in+(z*4), out+(z*4));
+
+/**
+   Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128
+   @param st      The Sober128 state
+   @param in      The plaintext (or ciphertext)
+   @param inlen   The length of the input (octets)
+   @param out     [out] The ciphertext (or plaintext), length inlen
+   @return CRYPT_OK if successful
+*/
+int sober128_stream_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
+{
+   ulong32 t;
+
+   if (inlen == 0) return CRYPT_OK; /* nothing to do */
+   LTC_ARGCHK(out != NULL);
+   LTC_ARGCHK(st  != NULL);
+
+   /* handle any previously buffered bytes */
+   while (st->nbuf != 0 && inlen != 0) {
+      *out++ = *in++ ^ (unsigned char)(st->sbuf & 0xFF);
+      st->sbuf >>= 8;
+      st->nbuf -= 8;
+      --inlen;
+   }
+
+#ifndef LTC_SMALL_CODE
+   /* do lots at a time, if there's enough to do */
+   while (inlen >= N*4) {
+      SROUND(0);
+      SROUND(1);
+      SROUND(2);
+      SROUND(3);
+      SROUND(4);
+      SROUND(5);
+      SROUND(6);
+      SROUND(7);
+      SROUND(8);
+      SROUND(9);
+      SROUND(10);
+      SROUND(11);
+      SROUND(12);
+      SROUND(13);
+      SROUND(14);
+      SROUND(15);
+      SROUND(16);
+      out    += 4*N;
+      in     += 4*N;
+      inlen  -= 4*N;
+   }
+#endif
+
+   /* do small or odd size buffers the slow way */
+   while (4 <= inlen) {
+      _cycle(st->R);
+      t = _nltap(st);
+      _xorword(t, in, out);
+      out    += 4;
+      in     += 4;
+      inlen  -= 4;
+   }
+
+   /* handle any trailing bytes */
+   if (inlen != 0) {
+      _cycle(st->R);
+      st->sbuf = _nltap(st);
+      st->nbuf = 32;
+      while (st->nbuf != 0 && inlen != 0) {
+          *out++ = *in++ ^ (unsigned char)(st->sbuf & 0xFF);
+          st->sbuf >>= 8;
+          st->nbuf -= 8;
+          --inlen;
+      }
+   }
+
+   return CRYPT_OK;
+}
+
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sober128/sober128_stream_done.c b/src/stream/sober128/sober128_stream_done.c
new file mode 100644
index 000000000..515667309
--- /dev/null
+++ b/src/stream/sober128/sober128_stream_done.c
@@ -0,0 +1,35 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+ @file sober128_stream.c
+ Implementation of SOBER-128 by Tom St Denis.
+ Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
+*/
+
+#ifdef LTC_SOBER128
+
+/**
+  Terminate and clear Sober128 state
+  @param st      The Sober128 state
+  @return CRYPT_OK on success
+*/
+int sober128_stream_done(sober128_state *st)
+{
+   LTC_ARGCHK(st != NULL);
+   XMEMSET(st, 0, sizeof(sober128_state));
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sober128/sober128_stream_keystream.c b/src/stream/sober128/sober128_stream_keystream.c
new file mode 100644
index 000000000..04f853e61
--- /dev/null
+++ b/src/stream/sober128/sober128_stream_keystream.c
@@ -0,0 +1,31 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+ @file sober128_stream.c
+ Implementation of SOBER-128 by Tom St Denis.
+ Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
+*/
+
+#ifdef LTC_SOBER128
+
+int sober128_stream_keystream(sober128_state *st, unsigned char *out, unsigned long outlen)
+{
+   if (outlen == 0) return CRYPT_OK; /* nothing to do */
+   LTC_ARGCHK(out != NULL);
+   XMEMSET(out, 0, outlen);
+   return sober128_stream_crypt(st, out, outlen, out);
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sober128/sober128_stream_setiv.c b/src/stream/sober128/sober128_stream_setiv.c
new file mode 100644
index 000000000..0846207f6
--- /dev/null
+++ b/src/stream/sober128/sober128_stream_setiv.c
@@ -0,0 +1,85 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+ @file sober128_stream.c
+ Implementation of SOBER-128 by Tom St Denis.
+ Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
+*/
+
+#ifdef LTC_SOBER128
+
+#define __LTC_SOBER128TAB_C__
+#include "sober128tab.c"
+
+#define LTC_SOBER128_STREAM_SETIV
+#include "sober128_stream_common.h"
+#undef  LTC_SOBER128_STREAM_SETIV
+
+
+/* initialise to previously saved register state
+ */
+static void _s128_reloadstate(sober128_state *st)
+{
+    int i;
+
+    for (i = 0; i < N; ++i) {
+        st->R[i] = st->initR[i];
+    }
+}
+
+
+/**
+  Set IV to the Sober128 state
+  @param st      The Sober12820 state
+  @param iv      The IV data to add
+  @param ivlen   The length of the IV (must be 12)
+  @return CRYPT_OK on success
+ */
+int sober128_stream_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen)
+{
+   ulong32 i, k;
+
+   LTC_ARGCHK(st != NULL);
+   LTC_ARGCHK(iv != NULL);
+   LTC_ARGCHK(ivlen > 0);
+
+   /* ok we are adding an IV then... */
+   _s128_reloadstate(st);
+
+   /* ivlen must be multiple of 4 bytes */
+   if ((ivlen & 3) != 0) {
+      return CRYPT_INVALID_KEYSIZE;
+   }
+
+   for (i = 0; i < ivlen; i += 4) {
+      LOAD32L(k, (unsigned char *)&iv[i]);
+      ADDKEY(k);
+      _cycle(st->R);
+      XORNL(_nltap(st));
+   }
+
+   /* also fold in the length of the key */
+   ADDKEY(ivlen);
+
+   /* now diffuse */
+   _s128_diffuse(st);
+   st->nbuf = 0;
+
+   return CRYPT_OK;
+}
+
+
+#endif
+
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sober128/sober128_stream_setup.c b/src/stream/sober128/sober128_stream_setup.c
new file mode 100644
index 000000000..7ed7b26c8
--- /dev/null
+++ b/src/stream/sober128/sober128_stream_setup.c
@@ -0,0 +1,106 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+ @file sober128_stream.c
+ Implementation of SOBER-128 by Tom St Denis.
+ Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
+*/
+
+#ifdef LTC_SOBER128
+
+#define __LTC_SOBER128TAB_C__
+#include "sober128tab.c"
+
+#define LTC_SOBER128_STREAM_SETUP
+#include "sober128_stream_common.h"
+#undef  LTC_SOBER128_STREAM_SETUP
+
+
+/*
+ * Save the current register state
+ */
+static void _s128_savestate(sober128_state *st)
+{
+    int i;
+    for (i = 0; i < N; ++i) {
+        st->initR[i] = st->R[i];
+    }
+}
+
+/*
+ * Initialise "konst"
+ */
+static void _s128_genkonst(sober128_state *st)
+{
+    ulong32 newkonst;
+
+    do {
+       _cycle(st->R);
+       newkonst = _nltap(st);
+    } while ((newkonst & 0xFF000000) == 0);
+    st->konst = newkonst;
+}
+
+
+/**
+   Initialize an Sober128 context (only the key)
+   @param st        [out] The destination of the Sober128 state
+   @param key       The secret key
+   @param keylen    The length of the secret key (octets)
+   @return CRYPT_OK if successful
+*/
+int sober128_stream_setup(sober128_state *st, const unsigned char *key, unsigned long keylen)
+{
+   ulong32 i, k;
+
+   LTC_ARGCHK(st  != NULL);
+   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(keylen > 0);
+
+   /* keylen must be multiple of 4 bytes */
+   if ((keylen & 3) != 0) {
+      return CRYPT_INVALID_KEYSIZE;
+   }
+
+   /* Register initialised to Fibonacci numbers */
+   st->R[0] = 1;
+   st->R[1] = 1;
+   for (i = 2; i < N; ++i) {
+      st->R[i] = st->R[i-1] + st->R[i-2];
+   }
+   st->konst = INITKONST;
+
+   for (i = 0; i < keylen; i += 4) {
+      LOAD32L(k, (unsigned char *)&key[i]);
+      ADDKEY(k);
+      _cycle(st->R);
+      XORNL(_nltap(st));
+   }
+
+   /* also fold in the length of the key */
+   ADDKEY(keylen);
+
+   /* now diffuse */
+   _s128_diffuse(st);
+   _s128_genkonst(st);
+   _s128_savestate(st);
+   st->nbuf = 0;
+
+   return CRYPT_OK;
+}
+
+
+#endif
+
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sosemanuk/sosemanuk_common.h b/src/stream/sosemanuk/sosemanuk_common.h
new file mode 100644
index 000000000..7d87882b7
--- /dev/null
+++ b/src/stream/sosemanuk/sosemanuk_common.h
@@ -0,0 +1,187 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/*
+ * This LTC implementation was adapted from:
+ *    http://www.ecrypt.eu.org/stream/e2-sosemanuk.html
+ */
+
+/*
+ * SOSEMANUK reference implementation.
+ *
+ * This code is supposed to run on any conforming C implementation (C90
+ * or later).
+ *
+ * (c) 2005 X-CRYPT project. This software is provided 'as-is', without
+ * any express or implied warranty. In no event will the authors be held
+ * liable for any damages arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to no restriction.
+ *
+ * Technical remarks and questions can be addressed to
+ * <thomas.pornin@cryptolog.com>
+ */
+
+#ifdef LTC_SOSEMANUK
+
+/*
+ * this code is common to sosemanuk_setup(), sosemanuk_setiv(), sosemanuk_crypt()
+ */
+
+/* ======================================================================== */
+
+/*
+ * We want (and sometimes need) to perform explicit truncations to 32 bits.
+ */
+#define T32(x)   ((x) & (ulong32)0xFFFFFFFF)
+
+/*
+ * Some of our functions will be tagged as "inline" to help the compiler
+ * optimize things. We use "inline" only if the compiler is advanced
+ * enough to understand it; C99 compilers, and pre-C99 versions of gcc,
+ * understand enough "inline" for our purposes.
+ */
+
+/* ======================================================================== */
+
+/*
+ * Serpent S-boxes, implemented in bitslice mode. These circuits have
+ * been published by Dag Arne Osvik ("Speeding up Serpent", published in
+ * the 3rd AES Candidate Conference) and work on five 32-bit registers:
+ * the four inputs, and a fifth scratch register. There are meant to be
+ * quite fast on Pentium-class processors. These are not the fastest
+ * published, but they are "fast enough" and they are unencumbered as
+ * far as intellectual property is concerned (note: these are rewritten
+ * from the article itself, and hence are not covered by the GPL on
+ * Dag's code, which was not used here).
+ *
+ * The output bits are permuted. Here is the correspondance:
+ *   S0:  1420
+ *   S1:  2031
+ *   S2:  2314
+ *   S3:  1234
+ *   S4:  1403
+ *   S5:  1302
+ *   S6:  0142
+ *   S7:  4310
+ * (for instance, the output of S0 is in "r1, r4, r2, r0").
+ */
+
+#define S0(r0, r1, r2, r3, r4)   do { \
+        r3 ^= r0;  r4  = r1; \
+        r1 &= r3;  r4 ^= r2; \
+        r1 ^= r0;  r0 |= r3; \
+        r0 ^= r4;  r4 ^= r3; \
+        r3 ^= r2;  r2 |= r1; \
+        r2 ^= r4;  r4 = ~r4; \
+        r4 |= r1;  r1 ^= r3; \
+        r1 ^= r4;  r3 |= r0; \
+        r1 ^= r3;  r4 ^= r3; \
+    } while (0)
+
+#define S1(r0, r1, r2, r3, r4)   do { \
+        r0 = ~r0;  r2 = ~r2; \
+        r4  = r0;  r0 &= r1; \
+        r2 ^= r0;  r0 |= r3; \
+        r3 ^= r2;  r1 ^= r0; \
+        r0 ^= r4;  r4 |= r1; \
+        r1 ^= r3;  r2 |= r0; \
+        r2 &= r4;  r0 ^= r1; \
+        r1 &= r2; \
+        r1 ^= r0;  r0 &= r2; \
+        r0 ^= r4; \
+    } while (0)
+
+#define S2(r0, r1, r2, r3, r4)   do { \
+        r4  = r0;  r0 &= r2; \
+        r0 ^= r3;  r2 ^= r1; \
+        r2 ^= r0;  r3 |= r4; \
+        r3 ^= r1;  r4 ^= r2; \
+        r1  = r3;  r3 |= r4; \
+        r3 ^= r0;  r0 &= r1; \
+        r4 ^= r0;  r1 ^= r3; \
+        r1 ^= r4;  r4 = ~r4; \
+    } while (0)
+
+#define S3(r0, r1, r2, r3, r4)   do { \
+        r4  = r0;  r0 |= r3; \
+        r3 ^= r1;  r1 &= r4; \
+        r4 ^= r2;  r2 ^= r3; \
+        r3 &= r0;  r4 |= r1; \
+        r3 ^= r4;  r0 ^= r1; \
+        r4 &= r0;  r1 ^= r3; \
+        r4 ^= r2;  r1 |= r0; \
+        r1 ^= r2;  r0 ^= r3; \
+        r2  = r1;  r1 |= r3; \
+        r1 ^= r0; \
+    } while (0)
+
+#define S4(r0, r1, r2, r3, r4)   do { \
+        r1 ^= r3;  r3 = ~r3; \
+        r2 ^= r3;  r3 ^= r0; \
+        r4  = r1;  r1 &= r3; \
+        r1 ^= r2;  r4 ^= r3; \
+        r0 ^= r4;  r2 &= r4; \
+        r2 ^= r0;  r0 &= r1; \
+        r3 ^= r0;  r4 |= r1; \
+        r4 ^= r0;  r0 |= r3; \
+        r0 ^= r2;  r2 &= r3; \
+        r0 = ~r0;  r4 ^= r2; \
+    } while (0)
+
+#define S5(r0, r1, r2, r3, r4)   do { \
+        r0 ^= r1;  r1 ^= r3; \
+        r3 = ~r3;  r4  = r1; \
+        r1 &= r0;  r2 ^= r3; \
+        r1 ^= r2;  r2 |= r4; \
+        r4 ^= r3;  r3 &= r1; \
+        r3 ^= r0;  r4 ^= r1; \
+        r4 ^= r2;  r2 ^= r0; \
+        r0 &= r3;  r2 = ~r2; \
+        r0 ^= r4;  r4 |= r3; \
+        r2 ^= r4; \
+    } while (0)
+
+#define S6(r0, r1, r2, r3, r4)   do { \
+        r2 = ~r2;  r4  = r3; \
+        r3 &= r0;  r0 ^= r4; \
+        r3 ^= r2;  r2 |= r4; \
+        r1 ^= r3;  r2 ^= r0; \
+        r0 |= r1;  r2 ^= r1; \
+        r4 ^= r0;  r0 |= r3; \
+        r0 ^= r2;  r4 ^= r3; \
+        r4 ^= r0;  r3 = ~r3; \
+        r2 &= r4; \
+        r2 ^= r3; \
+    } while (0)
+
+#define S7(r0, r1, r2, r3, r4)   do { \
+        r4  = r1;  r1 |= r2; \
+        r1 ^= r3;  r4 ^= r2; \
+        r2 ^= r1;  r3 |= r4; \
+        r3 &= r0;  r4 ^= r2; \
+        r3 ^= r1;  r1 |= r4; \
+        r1 ^= r0;  r0 |= r4; \
+        r0 ^= r2;  r1 ^= r4; \
+        r2 ^= r1;  r1 &= r0; \
+        r1 ^= r4;  r2 = ~r2; \
+        r2 |= r0; \
+        r4 ^= r2; \
+    } while (0)
+
+/* ======================================================================== */
+
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sosemanuk/sosemanuk.c b/src/stream/sosemanuk/sosemanuk_crypt.c
similarity index 53%
rename from src/stream/sosemanuk/sosemanuk.c
rename to src/stream/sosemanuk/sosemanuk_crypt.c
index 1c7cc27b5..de28dbe78 100644
--- a/src/stream/sosemanuk/sosemanuk.c
+++ b/src/stream/sosemanuk/sosemanuk_crypt.c
@@ -10,6 +10,12 @@
 /*
  * This LTC implementation was adapted from:
  *    http://www.ecrypt.eu.org/stream/e2-sosemanuk.html
+ *
+ * Sosemanuk specifications require:
+ *    1- a key of at least 128 bits (16 bytes), not exceeding 256 bits (32 bytes).
+ *    2- keys < 32 bytes are terminated with 0x01 followed by NULLs as needed.
+ *    3- an iv of 128 bits (16 bytes).
+ * See http://www.ecrypt.eu.org/stream/p3ciphers/sosemanuk/sosemanuk_p3.pdf
  */
 
 /*
@@ -34,411 +40,9 @@
 
 #ifdef LTC_SOSEMANUK
 
-/* ======================================================================== */
-
-/*
- * We want (and sometimes need) to perform explicit truncations to 32 bits.
- */
-#define T32(x)   ((x) & (ulong32)0xFFFFFFFF)
-
-/*
- * Some of our functions will be tagged as "inline" to help the compiler
- * optimize things. We use "inline" only if the compiler is advanced
- * enough to understand it; C99 compilers, and pre-C99 versions of gcc,
- * understand enough "inline" for our purposes.
- */
-
-/* ======================================================================== */
-
-/*
- * Serpent S-boxes, implemented in bitslice mode. These circuits have
- * been published by Dag Arne Osvik ("Speeding up Serpent", published in
- * the 3rd AES Candidate Conference) and work on five 32-bit registers:
- * the four inputs, and a fifth scratch register. There are meant to be
- * quite fast on Pentium-class processors. These are not the fastest
- * published, but they are "fast enough" and they are unencumbered as
- * far as intellectual property is concerned (note: these are rewritten
- * from the article itself, and hence are not covered by the GPL on
- * Dag's code, which was not used here).
- *
- * The output bits are permuted. Here is the correspondance:
- *   S0:  1420
- *   S1:  2031
- *   S2:  2314
- *   S3:  1234
- *   S4:  1403
- *   S5:  1302
- *   S6:  0142
- *   S7:  4310
- * (for instance, the output of S0 is in "r1, r4, r2, r0").
- */
-
-#define S0(r0, r1, r2, r3, r4)   do { \
-        r3 ^= r0;  r4  = r1; \
-        r1 &= r3;  r4 ^= r2; \
-        r1 ^= r0;  r0 |= r3; \
-        r0 ^= r4;  r4 ^= r3; \
-        r3 ^= r2;  r2 |= r1; \
-        r2 ^= r4;  r4 = ~r4; \
-        r4 |= r1;  r1 ^= r3; \
-        r1 ^= r4;  r3 |= r0; \
-        r1 ^= r3;  r4 ^= r3; \
-    } while (0)
-
-#define S1(r0, r1, r2, r3, r4)   do { \
-        r0 = ~r0;  r2 = ~r2; \
-        r4  = r0;  r0 &= r1; \
-        r2 ^= r0;  r0 |= r3; \
-        r3 ^= r2;  r1 ^= r0; \
-        r0 ^= r4;  r4 |= r1; \
-        r1 ^= r3;  r2 |= r0; \
-        r2 &= r4;  r0 ^= r1; \
-        r1 &= r2; \
-        r1 ^= r0;  r0 &= r2; \
-        r0 ^= r4; \
-    } while (0)
-
-#define S2(r0, r1, r2, r3, r4)   do { \
-        r4  = r0;  r0 &= r2; \
-        r0 ^= r3;  r2 ^= r1; \
-        r2 ^= r0;  r3 |= r4; \
-        r3 ^= r1;  r4 ^= r2; \
-        r1  = r3;  r3 |= r4; \
-        r3 ^= r0;  r0 &= r1; \
-        r4 ^= r0;  r1 ^= r3; \
-        r1 ^= r4;  r4 = ~r4; \
-    } while (0)
-
-#define S3(r0, r1, r2, r3, r4)   do { \
-        r4  = r0;  r0 |= r3; \
-        r3 ^= r1;  r1 &= r4; \
-        r4 ^= r2;  r2 ^= r3; \
-        r3 &= r0;  r4 |= r1; \
-        r3 ^= r4;  r0 ^= r1; \
-        r4 &= r0;  r1 ^= r3; \
-        r4 ^= r2;  r1 |= r0; \
-        r1 ^= r2;  r0 ^= r3; \
-        r2  = r1;  r1 |= r3; \
-        r1 ^= r0; \
-    } while (0)
-
-#define S4(r0, r1, r2, r3, r4)   do { \
-        r1 ^= r3;  r3 = ~r3; \
-        r2 ^= r3;  r3 ^= r0; \
-        r4  = r1;  r1 &= r3; \
-        r1 ^= r2;  r4 ^= r3; \
-        r0 ^= r4;  r2 &= r4; \
-        r2 ^= r0;  r0 &= r1; \
-        r3 ^= r0;  r4 |= r1; \
-        r4 ^= r0;  r0 |= r3; \
-        r0 ^= r2;  r2 &= r3; \
-        r0 = ~r0;  r4 ^= r2; \
-    } while (0)
+#include "sosemanuk_common.h"
 
-#define S5(r0, r1, r2, r3, r4)   do { \
-        r0 ^= r1;  r1 ^= r3; \
-        r3 = ~r3;  r4  = r1; \
-        r1 &= r0;  r2 ^= r3; \
-        r1 ^= r2;  r2 |= r4; \
-        r4 ^= r3;  r3 &= r1; \
-        r3 ^= r0;  r4 ^= r1; \
-        r4 ^= r2;  r2 ^= r0; \
-        r0 &= r3;  r2 = ~r2; \
-        r0 ^= r4;  r4 |= r3; \
-        r2 ^= r4; \
-    } while (0)
-
-#define S6(r0, r1, r2, r3, r4)   do { \
-        r2 = ~r2;  r4  = r3; \
-        r3 &= r0;  r0 ^= r4; \
-        r3 ^= r2;  r2 |= r4; \
-        r1 ^= r3;  r2 ^= r0; \
-        r0 |= r1;  r2 ^= r1; \
-        r4 ^= r0;  r0 |= r3; \
-        r0 ^= r2;  r4 ^= r3; \
-        r4 ^= r0;  r3 = ~r3; \
-        r2 &= r4; \
-        r2 ^= r3; \
-    } while (0)
-
-#define S7(r0, r1, r2, r3, r4)   do { \
-        r4  = r1;  r1 |= r2; \
-        r1 ^= r3;  r4 ^= r2; \
-        r2 ^= r1;  r3 |= r4; \
-        r3 &= r0;  r4 ^= r2; \
-        r3 ^= r1;  r1 |= r4; \
-        r1 ^= r0;  r0 |= r4; \
-        r0 ^= r2;  r1 ^= r4; \
-        r2 ^= r1;  r1 &= r0; \
-        r1 ^= r4;  r2 = ~r2; \
-        r2 |= r0; \
-        r4 ^= r2; \
-    } while (0)
-
-/*
- * The Serpent linear transform.
- */
-#define SERPENT_LT(x0, x1, x2, x3)  do { \
-        x0 = ROLc(x0, 13); \
-        x2 = ROLc(x2, 3); \
-        x1 = x1 ^ x0 ^ x2; \
-        x3 = x3 ^ x2 ^ T32(x0 << 3); \
-        x1 = ROLc(x1, 1); \
-        x3 = ROLc(x3, 7); \
-        x0 = x0 ^ x1 ^ x3; \
-        x2 = x2 ^ x3 ^ T32(x1 << 7); \
-        x0 = ROLc(x0, 5); \
-        x2 = ROLc(x2, 22); \
-    } while (0)
-
-/* ======================================================================== */
-
-/*
- * Initialize Sosemanuk's state by providing a key. The key is an array of
- * 1 to 32 bytes.
- * @param st       The Sosemanuk state
- * @param key      Key
- * @param keylen   Length of key in bytes
- * @return CRYPT_OK on success
- */
-int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen)
-{
-    /*
-     * This key schedule is actually a truncated Serpent key schedule.
-     * The key-derived words (w_i) are computed within the eight
-     * local variables w0 to w7, which are reused again and again.
-     */
-
-#define SKS(S, o0, o1, o2, o3, d0, d1, d2, d3)   do { \
-        ulong32 r0, r1, r2, r3, r4; \
-        r0 = w ## o0; \
-        r1 = w ## o1; \
-        r2 = w ## o2; \
-        r3 = w ## o3; \
-        S(r0, r1, r2, r3, r4); \
-        st->kc[i ++] = r ## d0; \
-        st->kc[i ++] = r ## d1; \
-        st->kc[i ++] = r ## d2; \
-        st->kc[i ++] = r ## d3; \
-    } while (0)
-
-#define SKS0    SKS(S0, 4, 5, 6, 7, 1, 4, 2, 0)
-#define SKS1    SKS(S1, 0, 1, 2, 3, 2, 0, 3, 1)
-#define SKS2    SKS(S2, 4, 5, 6, 7, 2, 3, 1, 4)
-#define SKS3    SKS(S3, 0, 1, 2, 3, 1, 2, 3, 4)
-#define SKS4    SKS(S4, 4, 5, 6, 7, 1, 4, 0, 3)
-#define SKS5    SKS(S5, 0, 1, 2, 3, 1, 3, 0, 2)
-#define SKS6    SKS(S6, 4, 5, 6, 7, 0, 1, 4, 2)
-#define SKS7    SKS(S7, 0, 1, 2, 3, 4, 3, 1, 0)
-
-#define WUP(wi, wi5, wi3, wi1, cc)   do { \
-        ulong32 tt = (wi) ^ (wi5) ^ (wi3) \
-            ^ (wi1) ^ (0x9E3779B9 ^ (ulong32)(cc)); \
-        (wi) = ROLc(tt, 11); \
-    } while (0)
-
-#define WUP0(cc)   do { \
-        WUP(w0, w3, w5, w7, cc); \
-        WUP(w1, w4, w6, w0, cc + 1); \
-        WUP(w2, w5, w7, w1, cc + 2); \
-        WUP(w3, w6, w0, w2, cc + 3); \
-    } while (0)
-
-#define WUP1(cc)   do { \
-        WUP(w4, w7, w1, w3, cc); \
-        WUP(w5, w0, w2, w4, cc + 1); \
-        WUP(w6, w1, w3, w5, cc + 2); \
-        WUP(w7, w2, w4, w6, cc + 3); \
-    } while (0)
-
-    unsigned char wbuf[32];
-    ulong32 w0, w1, w2, w3, w4, w5, w6, w7;
-    int i = 0;
-
-   LTC_ARGCHK(st  != NULL);
-   LTC_ARGCHK(key != NULL);
-   LTC_ARGCHK(keylen > 0 && keylen <= 32);
-
-    /*
-     * The key is copied into the wbuf[] buffer and padded to 256 bits
-     * as described in the Serpent specification.
-     */
-    XMEMCPY(wbuf, key, keylen);
-    if (keylen < 32) {
-        wbuf[keylen] = 0x01;
-        if (keylen < 31) {
-            XMEMSET(wbuf + keylen + 1, 0, 31 - keylen);
-        }
-    }
-
-    LOAD32L(w0, wbuf);
-    LOAD32L(w1, wbuf + 4);
-    LOAD32L(w2, wbuf + 8);
-    LOAD32L(w3, wbuf + 12);
-    LOAD32L(w4, wbuf + 16);
-    LOAD32L(w5, wbuf + 20);
-    LOAD32L(w6, wbuf + 24);
-    LOAD32L(w7, wbuf + 28);
-
-    WUP0(0);   SKS3;
-    WUP1(4);   SKS2;
-    WUP0(8);   SKS1;
-    WUP1(12);  SKS0;
-    WUP0(16);  SKS7;
-    WUP1(20);  SKS6;
-    WUP0(24);  SKS5;
-    WUP1(28);  SKS4;
-    WUP0(32);  SKS3;
-    WUP1(36);  SKS2;
-    WUP0(40);  SKS1;
-    WUP1(44);  SKS0;
-    WUP0(48);  SKS7;
-    WUP1(52);  SKS6;
-    WUP0(56);  SKS5;
-    WUP1(60);  SKS4;
-    WUP0(64);  SKS3;
-    WUP1(68);  SKS2;
-    WUP0(72);  SKS1;
-    WUP1(76);  SKS0;
-    WUP0(80);  SKS7;
-    WUP1(84);  SKS6;
-    WUP0(88);  SKS5;
-    WUP1(92);  SKS4;
-    WUP0(96);  SKS3;
-
-#undef SKS
-#undef SKS0
-#undef SKS1
-#undef SKS2
-#undef SKS3
-#undef SKS4
-#undef SKS5
-#undef SKS6
-#undef SKS7
-#undef WUP
-#undef WUP0
-#undef WUP1
-
-    return CRYPT_OK;
-}
-
-
-/*
- * Initialization continues by setting the IV. The IV length is up to 16 bytes.
- * If "ivlen" is 0 (no IV), then the "iv" parameter can be NULL.  If multiple
- * encryptions/decryptions are to be performed with the same key and
- * sosemanuk_done() has not been called, only sosemanuk_setiv() need be called
- * to set the state.
- * @param st       The Sosemanuk state
- * @param iv       Initialization vector
- * @param ivlen    Length of iv in bytes
- * @return CRYPT_OK on success
- */
-int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen)
-{
-
-    /*
-     * The Serpent key addition step.
-     */
-#define KA(zc, x0, x1, x2, x3)  do { \
-        x0 ^= st->kc[(zc)]; \
-        x1 ^= st->kc[(zc) + 1]; \
-        x2 ^= st->kc[(zc) + 2]; \
-        x3 ^= st->kc[(zc) + 3]; \
-    } while (0)
-
-    /*
-     * One Serpent round.
-     *   zc = current subkey counter
-     *   S = S-box macro for this round
-     *   i0 to i4 = input register numbers (the fifth is a scratch register)
-     *   o0 to o3 = output register numbers
-     */
-#define FSS(zc, S, i0, i1, i2, i3, i4, o0, o1, o2, o3)  do { \
-        KA(zc, r ## i0, r ## i1, r ## i2, r ## i3); \
-        S(r ## i0, r ## i1, r ## i2, r ## i3, r ## i4); \
-        SERPENT_LT(r ## o0, r ## o1, r ## o2, r ## o3); \
-    } while (0)
-
-    /*
-     * Last Serpent round. Contrary to the "true" Serpent, we keep
-     * the linear transformation for that last round.
-     */
-#define FSF(zc, S, i0, i1, i2, i3, i4, o0, o1, o2, o3)  do { \
-        KA(zc, r ## i0, r ## i1, r ## i2, r ## i3); \
-        S(r ## i0, r ## i1, r ## i2, r ## i3, r ## i4); \
-        SERPENT_LT(r ## o0, r ## o1, r ## o2, r ## o3); \
-        KA(zc + 4, r ## o0, r ## o1, r ## o2, r ## o3); \
-    } while (0)
-
-    ulong32 r0, r1, r2, r3, r4;
-    unsigned char ivtmp[16] = {0};
-
-    LTC_ARGCHK(st != NULL);
-    LTC_ARGCHK(ivlen <= 16);
-    LTC_ARGCHK(iv != NULL || ivlen == 0);
-
-    if (ivlen > 0) XMEMCPY(ivtmp, iv, ivlen);
-
-    /*
-     * Decode IV into four 32-bit words (little-endian).
-     */
-    LOAD32L(r0, ivtmp);
-    LOAD32L(r1, ivtmp + 4);
-    LOAD32L(r2, ivtmp + 8);
-    LOAD32L(r3, ivtmp + 12);
-
-    /*
-     * Encrypt IV with Serpent24. Some values are extracted from the
-     * output of the twelfth, eighteenth and twenty-fourth rounds.
-     */
-    FSS(0, S0, 0, 1, 2, 3, 4, 1, 4, 2, 0);
-    FSS(4, S1, 1, 4, 2, 0, 3, 2, 1, 0, 4);
-    FSS(8, S2, 2, 1, 0, 4, 3, 0, 4, 1, 3);
-    FSS(12, S3, 0, 4, 1, 3, 2, 4, 1, 3, 2);
-    FSS(16, S4, 4, 1, 3, 2, 0, 1, 0, 4, 2);
-    FSS(20, S5, 1, 0, 4, 2, 3, 0, 2, 1, 4);
-    FSS(24, S6, 0, 2, 1, 4, 3, 0, 2, 3, 1);
-    FSS(28, S7, 0, 2, 3, 1, 4, 4, 1, 2, 0);
-    FSS(32, S0, 4, 1, 2, 0, 3, 1, 3, 2, 4);
-    FSS(36, S1, 1, 3, 2, 4, 0, 2, 1, 4, 3);
-    FSS(40, S2, 2, 1, 4, 3, 0, 4, 3, 1, 0);
-    FSS(44, S3, 4, 3, 1, 0, 2, 3, 1, 0, 2);
-    st->s09 = r3;
-    st->s08 = r1;
-    st->s07 = r0;
-    st->s06 = r2;
-
-    FSS(48, S4, 3, 1, 0, 2, 4, 1, 4, 3, 2);
-    FSS(52, S5, 1, 4, 3, 2, 0, 4, 2, 1, 3);
-    FSS(56, S6, 4, 2, 1, 3, 0, 4, 2, 0, 1);
-    FSS(60, S7, 4, 2, 0, 1, 3, 3, 1, 2, 4);
-    FSS(64, S0, 3, 1, 2, 4, 0, 1, 0, 2, 3);
-    FSS(68, S1, 1, 0, 2, 3, 4, 2, 1, 3, 0);
-    st->r1  = r2;
-    st->s04 = r1;
-    st->r2  = r3;
-    st->s05 = r0;
-
-    FSS(72, S2, 2, 1, 3, 0, 4, 3, 0, 1, 4);
-    FSS(76, S3, 3, 0, 1, 4, 2, 0, 1, 4, 2);
-    FSS(80, S4, 0, 1, 4, 2, 3, 1, 3, 0, 2);
-    FSS(84, S5, 1, 3, 0, 2, 4, 3, 2, 1, 0);
-    FSS(88, S6, 3, 2, 1, 0, 4, 3, 2, 4, 1);
-    FSF(92, S7, 3, 2, 4, 1, 0, 0, 1, 2, 3);
-    st->s03 = r0;
-    st->s02 = r1;
-    st->s01 = r2;
-    st->s00 = r3;
-
-    st->ptr = sizeof(st->buf);
-
-#undef KA
-#undef FSS
-#undef FSF
-
-    return CRYPT_OK;
-}
+/* -------------------------------------------------------------------------- */
 
 /*
  * Multiplication by alpha: alpha * x = T32(x << 8) ^ mul_a[x >> 24]
@@ -580,6 +184,7 @@ static const ulong32 mul_ia[] = {
     0x9EE2651C, 0x86ED25D1, 0xAEFCE52F, 0xB6F3A5E2
 };
 
+/* -------------------------------------------------------------------------- */
 
 /*
  * Compute the next block of bits of output stream. This is equivalent
@@ -717,6 +322,8 @@ static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *st)
     st->r2 = r2;
 }
 
+/* -------------------------------------------------------------------------- */
+
 /*
  * Combine buffers in1[] and in2[] by XOR, result in out[]. The length
  * is "datalen" (in bytes). Partial overlap of out[] with either in1[]
@@ -726,11 +333,11 @@ static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *st)
 static LTC_INLINE void _xorbuf(const unsigned char *in1, const unsigned char *in2,
     unsigned char *out, unsigned long datalen)
 {
-    while (datalen -- > 0) {
+    while (datalen -- > 0)
         *out ++ = *in1 ++ ^ *in2 ++;
-    }
 }
 
+/* -------------------------------------------------------------------------- */
 
 /*
  * Cipher operation, as a stream cipher: data is read from the "in"
@@ -753,9 +360,8 @@ int sosemanuk_crypt(sosemanuk_state *st,
     if (st->ptr < (sizeof(st->buf))) {
         unsigned long rlen = (sizeof(st->buf)) - st->ptr;
 
-        if (rlen > inlen) {
+        if (rlen > inlen)
             rlen = inlen;
-        }
         _xorbuf(st->buf + st->ptr, in, out, rlen);
         in += rlen;
         out += rlen;
@@ -778,37 +384,7 @@ int sosemanuk_crypt(sosemanuk_state *st,
     return CRYPT_OK;
 }
 
-
-
-/*
- * Cipher operation, as a PRNG: the provided output buffer is filled with
- * pseudo-random bytes as output from the stream cipher.
- * @param st       The Sosemanuk state
- * @param out      Data out
- * @param outlen   Length of output in bytes
- * @return CRYPT_OK on success
- */
-int sosemanuk_keystream(sosemanuk_state *st, unsigned char *out, unsigned long outlen)
-{
-   if (outlen == 0) return CRYPT_OK; /* nothing to do */
-   LTC_ARGCHK(out != NULL);
-   XMEMSET(out, 0, outlen);
-   return sosemanuk_crypt(st, out, outlen, out);
-}
-
-
-/*
- * Terminate and clear Sosemanuk key context
- * @param st      The Sosemanuk state
- * @return CRYPT_OK on success
- */
-int sosemanuk_done(sosemanuk_state *st)
-{
-   LTC_ARGCHK(st != NULL);
-   XMEMSET(st, 0, sizeof(sosemanuk_state));
-   return CRYPT_OK;
-}
-
+/* -------------------------------------------------------------------------- */
 
 #endif
 
diff --git a/src/stream/sosemanuk/sosemanuk_done.c b/src/stream/sosemanuk/sosemanuk_done.c
new file mode 100644
index 000000000..038fc971b
--- /dev/null
+++ b/src/stream/sosemanuk/sosemanuk_done.c
@@ -0,0 +1,59 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/*
+ * This LTC implementation was adapted from:
+ *    http://www.ecrypt.eu.org/stream/e2-sosemanuk.html
+ *
+ * Sosemanuk specifications require:
+ *    1- a key of at least 128 bits (16 bytes), not exceeding 256 bits (32 bytes).
+ *    2- keys < 32 bytes are terminated with 0x01 followed by NULLs as needed.
+ *    3- an iv of 128 bits (16 bytes).
+ * See http://www.ecrypt.eu.org/stream/p3ciphers/sosemanuk/sosemanuk_p3.pdf
+ */
+
+/*
+ * SOSEMANUK reference implementation.
+ *
+ * This code is supposed to run on any conforming C implementation (C90
+ * or later).
+ *
+ * (c) 2005 X-CRYPT project. This software is provided 'as-is', without
+ * any express or implied warranty. In no event will the authors be held
+ * liable for any damages arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to no restriction.
+ *
+ * Technical remarks and questions can be addressed to
+ * <thomas.pornin@cryptolog.com>
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_SOSEMANUK
+
+/*
+ * Terminate and clear Sosemanuk key context
+ * @param st      The Sosemanuk state
+ * @return CRYPT_OK on success
+ */
+int sosemanuk_done(sosemanuk_state *st)
+{
+   LTC_ARGCHK(st != NULL);
+   XMEMSET(st, 0, sizeof(sosemanuk_state));
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sosemanuk/sosemanuk_keystream.c b/src/stream/sosemanuk/sosemanuk_keystream.c
new file mode 100644
index 000000000..3d7a5ae67
--- /dev/null
+++ b/src/stream/sosemanuk/sosemanuk_keystream.c
@@ -0,0 +1,63 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/*
+ * This LTC implementation was adapted from:
+ *    http://www.ecrypt.eu.org/stream/e2-sosemanuk.html
+ *
+ * Sosemanuk specifications require:
+ *    1- a key of at least 128 bits (16 bytes), not exceeding 256 bits (32 bytes).
+ *    2- keys < 32 bytes are terminated with 0x01 followed by NULLs as needed.
+ *    3- an iv of 128 bits (16 bytes).
+ * See http://www.ecrypt.eu.org/stream/p3ciphers/sosemanuk/sosemanuk_p3.pdf
+ */
+
+/*
+ * SOSEMANUK reference implementation.
+ *
+ * This code is supposed to run on any conforming C implementation (C90
+ * or later).
+ *
+ * (c) 2005 X-CRYPT project. This software is provided 'as-is', without
+ * any express or implied warranty. In no event will the authors be held
+ * liable for any damages arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to no restriction.
+ *
+ * Technical remarks and questions can be addressed to
+ * <thomas.pornin@cryptolog.com>
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_SOSEMANUK
+
+/*
+ * Cipher operation, as a PRNG: the provided output buffer is filled with
+ * pseudo-random bytes as output from the stream cipher.
+ * @param st       The Sosemanuk state
+ * @param out      Data out
+ * @param outlen   Length of output in bytes
+ * @return CRYPT_OK on success
+ */
+int sosemanuk_keystream(sosemanuk_state *st, unsigned char *out, unsigned long outlen)
+{
+   if (outlen == 0) return CRYPT_OK; /* nothing to do */
+   LTC_ARGCHK(out != NULL);
+   XMEMSET(out, 0, outlen);
+   return sosemanuk_crypt(st, out, outlen, out);
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sosemanuk/sosemanuk_setiv.c b/src/stream/sosemanuk/sosemanuk_setiv.c
new file mode 100644
index 000000000..951d0982c
--- /dev/null
+++ b/src/stream/sosemanuk/sosemanuk_setiv.c
@@ -0,0 +1,181 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/*
+ * This LTC implementation was adapted from:
+ *    http://www.ecrypt.eu.org/stream/e2-sosemanuk.html
+ */
+
+/*
+ * SOSEMANUK reference implementation.
+ *
+ * This code is supposed to run on any conforming C implementation (C90
+ * or later).
+ *
+ * (c) 2005 X-CRYPT project. This software is provided 'as-is', without
+ * any express or implied warranty. In no event will the authors be held
+ * liable for any damages arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to no restriction.
+ *
+ * Technical remarks and questions can be addressed to
+ * <thomas.pornin@cryptolog.com>
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_SOSEMANUK
+
+#include "sosemanuk_common.h"
+
+/* ======================================================================== */
+
+/*
+ * The Serpent linear transform.
+ */
+#define SERPENT_LT(x0, x1, x2, x3)  do { \
+        x0 = ROLc(x0, 13); \
+        x2 = ROLc(x2, 3); \
+        x1 = x1 ^ x0 ^ x2; \
+        x3 = x3 ^ x2 ^ T32(x0 << 3); \
+        x1 = ROLc(x1, 1); \
+        x3 = ROLc(x3, 7); \
+        x0 = x0 ^ x1 ^ x3; \
+        x2 = x2 ^ x3 ^ T32(x1 << 7); \
+        x0 = ROLc(x0, 5); \
+        x2 = ROLc(x2, 22); \
+    } while (0)
+
+/* ======================================================================== */
+
+/*
+ * Initialization continues by setting the IV. The IV length is up to 16 bytes.
+ * If "ivlen" is 0 (no IV), then the "iv" parameter can be NULL.  If multiple
+ * encryptions/decryptions are to be performed with the same key and
+ * sosemanuk_done() has not been called, only sosemanuk_setiv() need be called
+ * to set the state.
+ * @param st       The Sosemanuk state
+ * @param iv       Initialization vector
+ * @param ivlen    Length of iv in bytes
+ * @return CRYPT_OK on success
+ */
+int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen)
+{
+
+    /*
+     * The Serpent key addition step.
+     */
+#define KA(zc, x0, x1, x2, x3)  do { \
+        x0 ^= st->kc[(zc)]; \
+        x1 ^= st->kc[(zc) + 1]; \
+        x2 ^= st->kc[(zc) + 2]; \
+        x3 ^= st->kc[(zc) + 3]; \
+    } while (0)
+
+    /*
+     * One Serpent round.
+     *   zc = current subkey counter
+     *   S = S-box macro for this round
+     *   i0 to i4 = input register numbers (the fifth is a scratch register)
+     *   o0 to o3 = output register numbers
+     */
+#define FSS(zc, S, i0, i1, i2, i3, i4, o0, o1, o2, o3)  do { \
+        KA(zc, r ## i0, r ## i1, r ## i2, r ## i3); \
+        S(r ## i0, r ## i1, r ## i2, r ## i3, r ## i4); \
+        SERPENT_LT(r ## o0, r ## o1, r ## o2, r ## o3); \
+    } while (0)
+
+    /*
+     * Last Serpent round. Contrary to the "true" Serpent, we keep
+     * the linear transformation for that last round.
+     */
+#define FSF(zc, S, i0, i1, i2, i3, i4, o0, o1, o2, o3)  do { \
+        KA(zc, r ## i0, r ## i1, r ## i2, r ## i3); \
+        S(r ## i0, r ## i1, r ## i2, r ## i3, r ## i4); \
+        SERPENT_LT(r ## o0, r ## o1, r ## o2, r ## o3); \
+        KA(zc + 4, r ## o0, r ## o1, r ## o2, r ## o3); \
+    } while (0)
+
+    ulong32 r0, r1, r2, r3, r4;
+    unsigned char ivtmp[16] = {0};
+
+    LTC_ARGCHK(st != NULL);
+    LTC_ARGCHK(ivlen <= 16);
+    LTC_ARGCHK(iv != NULL || ivlen == 0);
+
+    if (ivlen > 0) XMEMCPY(ivtmp, iv, ivlen);
+
+    /*
+     * Decode IV into four 32-bit words (little-endian).
+     */
+    LOAD32L(r0, ivtmp);
+    LOAD32L(r1, ivtmp + 4);
+    LOAD32L(r2, ivtmp + 8);
+    LOAD32L(r3, ivtmp + 12);
+
+    /*
+     * Encrypt IV with Serpent24. Some values are extracted from the
+     * output of the twelfth, eighteenth and twenty-fourth rounds.
+     */
+    FSS(0, S0, 0, 1, 2, 3, 4, 1, 4, 2, 0);
+    FSS(4, S1, 1, 4, 2, 0, 3, 2, 1, 0, 4);
+    FSS(8, S2, 2, 1, 0, 4, 3, 0, 4, 1, 3);
+    FSS(12, S3, 0, 4, 1, 3, 2, 4, 1, 3, 2);
+    FSS(16, S4, 4, 1, 3, 2, 0, 1, 0, 4, 2);
+    FSS(20, S5, 1, 0, 4, 2, 3, 0, 2, 1, 4);
+    FSS(24, S6, 0, 2, 1, 4, 3, 0, 2, 3, 1);
+    FSS(28, S7, 0, 2, 3, 1, 4, 4, 1, 2, 0);
+    FSS(32, S0, 4, 1, 2, 0, 3, 1, 3, 2, 4);
+    FSS(36, S1, 1, 3, 2, 4, 0, 2, 1, 4, 3);
+    FSS(40, S2, 2, 1, 4, 3, 0, 4, 3, 1, 0);
+    FSS(44, S3, 4, 3, 1, 0, 2, 3, 1, 0, 2);
+    st->s09 = r3;
+    st->s08 = r1;
+    st->s07 = r0;
+    st->s06 = r2;
+
+    FSS(48, S4, 3, 1, 0, 2, 4, 1, 4, 3, 2);
+    FSS(52, S5, 1, 4, 3, 2, 0, 4, 2, 1, 3);
+    FSS(56, S6, 4, 2, 1, 3, 0, 4, 2, 0, 1);
+    FSS(60, S7, 4, 2, 0, 1, 3, 3, 1, 2, 4);
+    FSS(64, S0, 3, 1, 2, 4, 0, 1, 0, 2, 3);
+    FSS(68, S1, 1, 0, 2, 3, 4, 2, 1, 3, 0);
+    st->r1  = r2;
+    st->s04 = r1;
+    st->r2  = r3;
+    st->s05 = r0;
+
+    FSS(72, S2, 2, 1, 3, 0, 4, 3, 0, 1, 4);
+    FSS(76, S3, 3, 0, 1, 4, 2, 0, 1, 4, 2);
+    FSS(80, S4, 0, 1, 4, 2, 3, 1, 3, 0, 2);
+    FSS(84, S5, 1, 3, 0, 2, 4, 3, 2, 1, 0);
+    FSS(88, S6, 3, 2, 1, 0, 4, 3, 2, 4, 1);
+    FSF(92, S7, 3, 2, 4, 1, 0, 0, 1, 2, 3);
+    st->s03 = r0;
+    st->s02 = r1;
+    st->s01 = r2;
+    st->s00 = r3;
+
+    st->ptr = sizeof(st->buf);
+
+#undef KA
+#undef FSS
+#undef FSF
+
+    return CRYPT_OK;
+}
+
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/stream/sosemanuk/sosemanuk_setup.c b/src/stream/sosemanuk/sosemanuk_setup.c
new file mode 100644
index 000000000..e40f41cd5
--- /dev/null
+++ b/src/stream/sosemanuk/sosemanuk_setup.c
@@ -0,0 +1,176 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/*
+ * This LTC implementation was adapted from:
+ *    http://www.ecrypt.eu.org/stream/e2-sosemanuk.html
+ */
+
+/*
+ * SOSEMANUK reference implementation.
+ *
+ * This code is supposed to run on any conforming C implementation (C90
+ * or later).
+ *
+ * (c) 2005 X-CRYPT project. This software is provided 'as-is', without
+ * any express or implied warranty. In no event will the authors be held
+ * liable for any damages arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to no restriction.
+ *
+ * Technical remarks and questions can be addressed to
+ * <thomas.pornin@cryptolog.com>
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_SOSEMANUK
+
+#include "sosemanuk_common.h"
+
+/* ======================================================================== */
+
+/*
+ * Initialize Sosemanuk's state by providing a key. The key is an array of
+ * 1 to 32 bytes.
+ * @param st       The Sosemanuk state
+ * @param key      Key
+ * @param keylen   Length of key in bytes
+ * @return CRYPT_OK on success
+ */
+int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen)
+{
+    /*
+     * This key schedule is actually a truncated Serpent key schedule.
+     * The key-derived words (w_i) are computed within the eight
+     * local variables w0 to w7, which are reused again and again.
+     */
+
+#define SKS(S, o0, o1, o2, o3, d0, d1, d2, d3)   do { \
+        ulong32 r0, r1, r2, r3, r4; \
+        r0 = w ## o0; \
+        r1 = w ## o1; \
+        r2 = w ## o2; \
+        r3 = w ## o3; \
+        S(r0, r1, r2, r3, r4); \
+        st->kc[i ++] = r ## d0; \
+        st->kc[i ++] = r ## d1; \
+        st->kc[i ++] = r ## d2; \
+        st->kc[i ++] = r ## d3; \
+    } while (0)
+
+#define SKS0    SKS(S0, 4, 5, 6, 7, 1, 4, 2, 0)
+#define SKS1    SKS(S1, 0, 1, 2, 3, 2, 0, 3, 1)
+#define SKS2    SKS(S2, 4, 5, 6, 7, 2, 3, 1, 4)
+#define SKS3    SKS(S3, 0, 1, 2, 3, 1, 2, 3, 4)
+#define SKS4    SKS(S4, 4, 5, 6, 7, 1, 4, 0, 3)
+#define SKS5    SKS(S5, 0, 1, 2, 3, 1, 3, 0, 2)
+#define SKS6    SKS(S6, 4, 5, 6, 7, 0, 1, 4, 2)
+#define SKS7    SKS(S7, 0, 1, 2, 3, 4, 3, 1, 0)
+
+#define WUP(wi, wi5, wi3, wi1, cc)   do { \
+        ulong32 tt = (wi) ^ (wi5) ^ (wi3) \
+            ^ (wi1) ^ (0x9E3779B9 ^ (ulong32)(cc)); \
+        (wi) = ROLc(tt, 11); \
+    } while (0)
+
+#define WUP0(cc)   do { \
+        WUP(w0, w3, w5, w7, cc); \
+        WUP(w1, w4, w6, w0, cc + 1); \
+        WUP(w2, w5, w7, w1, cc + 2); \
+        WUP(w3, w6, w0, w2, cc + 3); \
+    } while (0)
+
+#define WUP1(cc)   do { \
+        WUP(w4, w7, w1, w3, cc); \
+        WUP(w5, w0, w2, w4, cc + 1); \
+        WUP(w6, w1, w3, w5, cc + 2); \
+        WUP(w7, w2, w4, w6, cc + 3); \
+    } while (0)
+
+    unsigned char wbuf[32];
+    ulong32 w0, w1, w2, w3, w4, w5, w6, w7;
+    int i = 0;
+
+   LTC_ARGCHK(st  != NULL);
+   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(keylen > 0 && keylen <= 32);
+
+    /*
+     * The key is copied into the wbuf[] buffer and padded to 256 bits
+     * as described in the Serpent specification.
+     */
+    XMEMCPY(wbuf, key, keylen);
+    if (keylen < 32) {
+        wbuf[keylen] = 0x01;
+        if (keylen < 31) {
+            XMEMSET(wbuf + keylen + 1, 0, 31 - keylen);
+        }
+    }
+
+    LOAD32L(w0, wbuf);
+    LOAD32L(w1, wbuf + 4);
+    LOAD32L(w2, wbuf + 8);
+    LOAD32L(w3, wbuf + 12);
+    LOAD32L(w4, wbuf + 16);
+    LOAD32L(w5, wbuf + 20);
+    LOAD32L(w6, wbuf + 24);
+    LOAD32L(w7, wbuf + 28);
+
+    WUP0(0);   SKS3;
+    WUP1(4);   SKS2;
+    WUP0(8);   SKS1;
+    WUP1(12);  SKS0;
+    WUP0(16);  SKS7;
+    WUP1(20);  SKS6;
+    WUP0(24);  SKS5;
+    WUP1(28);  SKS4;
+    WUP0(32);  SKS3;
+    WUP1(36);  SKS2;
+    WUP0(40);  SKS1;
+    WUP1(44);  SKS0;
+    WUP0(48);  SKS7;
+    WUP1(52);  SKS6;
+    WUP0(56);  SKS5;
+    WUP1(60);  SKS4;
+    WUP0(64);  SKS3;
+    WUP1(68);  SKS2;
+    WUP0(72);  SKS1;
+    WUP1(76);  SKS0;
+    WUP0(80);  SKS7;
+    WUP1(84);  SKS6;
+    WUP0(88);  SKS5;
+    WUP1(92);  SKS4;
+    WUP0(96);  SKS3;
+
+#undef SKS
+#undef SKS0
+#undef SKS1
+#undef SKS2
+#undef SKS3
+#undef SKS4
+#undef SKS5
+#undef SKS6
+#undef SKS7
+#undef WUP
+#undef WUP0
+#undef WUP1
+
+    return CRYPT_OK;
+}
+
+
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */