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"
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2719,13 +2755,33 @@
Name="sober128"
>
+
+
+
+
+
+
+
+
+
+
@@ -2779,13 +2835,33 @@
Name="sosemanuk"
>
+
+
+
+
+
+
+
+
+
+
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
+ *
+ */
+
+#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
+ *
+ */
+
+#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
+ *
+ */
+
+#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
+ *
+ */
+
+#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
+ *
+ */
+
+#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$ */