diff options
author | lloyd <[email protected]> | 2009-03-31 01:51:32 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-03-31 01:51:32 +0000 |
commit | 1309862b2d60622129ba5f3fdaadc8b763d842a8 (patch) | |
tree | 3be10e240f1a7f5b88a1d4922d00f261b6b18488 /src | |
parent | 96d6eb6f29c55e16a37cf11899547886f735b065 (diff) |
Partially unroll the round structure, enough so that the subkey accesses
can be done directly, so there is no need to copy the key several times
for the key schedule (since the GOST 'key schedule' is very simple and the
access pattern can now be directly inserted into the code). Looks to be
about 10% faster on my Core2, as well.
Diffstat (limited to 'src')
-rw-r--r-- | src/block/gost_28147/gost_28147.cpp | 74 | ||||
-rw-r--r-- | src/block/gost_28147/gost_28147.h | 2 |
2 files changed, 40 insertions, 36 deletions
diff --git a/src/block/gost_28147/gost_28147.cpp b/src/block/gost_28147/gost_28147.cpp index 0f29102de..d433924fc 100644 --- a/src/block/gost_28147/gost_28147.cpp +++ b/src/block/gost_28147/gost_28147.cpp @@ -37,29 +37,43 @@ GOST_28147_89::GOST_28147_89() : BlockCipher(8, 32) } /* +* Two rounds of GOST +*/ +#define GOST_2ROUND(N1, N2, R1, R2) \ + { \ + u32bit T0 = N1 + EK[R1]; \ + N2 ^= SBOX[get_byte(3, T0)] | \ + SBOX[get_byte(2, T0)+256] | \ + SBOX[get_byte(1, T0)+512] | \ + SBOX[get_byte(0, T0)+768]; \ + \ + T0 = N2 + EK[R2]; \ + N1 ^= SBOX[get_byte(3, T0)] | \ + SBOX[get_byte(2, T0)+256] | \ + SBOX[get_byte(1, T0)+512] | \ + SBOX[get_byte(0, T0)+768]; \ + } + +/* * GOST Encryption */ void GOST_28147_89::enc(const byte in[], byte out[]) const { u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1); - for(u32bit j = 0; j != 32; j += 2) + for(size_t i = 0; i != 3; ++i) { - u32bit T0; - - T0 = N1 + EK[j]; - N2 ^= SBOX[get_byte(3, T0)] | - SBOX[get_byte(2, T0)+256] | - SBOX[get_byte(1, T0)+512] | - SBOX[get_byte(0, T0)+768]; - - T0 = N2 + EK[j+1]; - N1 ^= SBOX[get_byte(3, T0)] | - SBOX[get_byte(2, T0)+256] | - SBOX[get_byte(1, T0)+512] | - SBOX[get_byte(0, T0)+768]; + GOST_2ROUND(N1, N2, 0, 1); + GOST_2ROUND(N1, N2, 2, 3); + GOST_2ROUND(N1, N2, 4, 5); + GOST_2ROUND(N1, N2, 6, 7); } + GOST_2ROUND(N1, N2, 7, 6); + GOST_2ROUND(N1, N2, 5, 4); + GOST_2ROUND(N1, N2, 3, 2); + GOST_2ROUND(N1, N2, 1, 0); + store_le(out, N2, N1); } @@ -70,21 +84,17 @@ void GOST_28147_89::dec(const byte in[], byte out[]) const { u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1); - for(u32bit j = 0; j != 32; j += 2) + GOST_2ROUND(N1, N2, 0, 1); + GOST_2ROUND(N1, N2, 2, 3); + GOST_2ROUND(N1, N2, 4, 5); + GOST_2ROUND(N1, N2, 6, 7); + + for(size_t i = 0; i != 3; ++i) { - u32bit T0; - - T0 = N1 + EK[31-j]; - N2 ^= SBOX[get_byte(3, T0)] | - SBOX[get_byte(2, T0)+256] | - SBOX[get_byte(1, T0)+512] | - SBOX[get_byte(0, T0)+768]; - - T0 = N2 + EK[30-j]; - N1 ^= SBOX[get_byte(3, T0)] | - SBOX[get_byte(2, T0)+256] | - SBOX[get_byte(1, T0)+512] | - SBOX[get_byte(0, T0)+768]; + GOST_2ROUND(N1, N2, 7, 6); + GOST_2ROUND(N1, N2, 5, 4); + GOST_2ROUND(N1, N2, 3, 2); + GOST_2ROUND(N1, N2, 1, 0); } store_le(out, N2, N1); @@ -96,13 +106,7 @@ void GOST_28147_89::dec(const byte in[], byte out[]) const void GOST_28147_89::key_schedule(const byte key[], u32bit) { for(u32bit j = 0; j != 8; ++j) - { - u32bit K = load_le<u32bit>(key, j); - EK[j] = EK[j+8] = EK[j+16] = K; - } - - for(u32bit j = 24; j != 32; ++j) - EK[j] = EK[7-(j-24)]; + EK[j] = load_le<u32bit>(key, j); } } diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h index a58927e28..1ff04b890 100644 --- a/src/block/gost_28147/gost_28147.h +++ b/src/block/gost_28147/gost_28147.h @@ -30,7 +30,7 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher void key_schedule(const byte[], u32bit); SecureBuffer<u32bit, 1024> SBOX; - SecureBuffer<u32bit, 32> EK; + SecureBuffer<u32bit, 8> EK; }; } |