aboutsummaryrefslogtreecommitdiffstats
path: root/src/block/rc2/rc2.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-08-11 02:31:17 +0000
committerlloyd <[email protected]>2009-08-11 02:31:17 +0000
commitf51841ba5237952dda3e76df643d3ae13bed3df5 (patch)
tree7fd004a107bae55a5f87c4e8bc35b0012334b29b /src/block/rc2/rc2.cpp
parent34eb8de4ed014ab8913bdb34b096d60880b1c14a (diff)
Change the BlockCipher interface to support multi-block encryption and
decryption. Currently only used for counter mode. Doesn't offer much advantage as-is (though might help slightly, in terms of cache effects), but allows for SIMD implementations to process multiple blocks in parallel when possible. Particularly thinking here of Serpent; TEA/XTEA also seem promising in this sense, as is Threefish once that is implemented as a standalone block cipher.
Diffstat (limited to 'src/block/rc2/rc2.cpp')
-rw-r--r--src/block/rc2/rc2.cpp104
1 files changed, 58 insertions, 46 deletions
diff --git a/src/block/rc2/rc2.cpp b/src/block/rc2/rc2.cpp
index 5827bdb68..b5e4a7d50 100644
--- a/src/block/rc2/rc2.cpp
+++ b/src/block/rc2/rc2.cpp
@@ -14,73 +14,85 @@ namespace Botan {
/*
* RC2 Encryption
*/
-void RC2::enc(const byte in[], byte out[]) const
+void RC2::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit R0 = load_le<u16bit>(in, 0);
- u16bit R1 = load_le<u16bit>(in, 1);
- u16bit R2 = load_le<u16bit>(in, 2);
- u16bit R3 = load_le<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 16; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R0 += (R1 & ~R3) + (R2 & R3) + K[4*j];
- R0 = rotate_left(R0, 1);
+ u16bit R0 = load_le<u16bit>(in, 0);
+ u16bit R1 = load_le<u16bit>(in, 1);
+ u16bit R2 = load_le<u16bit>(in, 2);
+ u16bit R3 = load_le<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 16; ++j)
+ {
+ R0 += (R1 & ~R3) + (R2 & R3) + K[4*j];
+ R0 = rotate_left(R0, 1);
- R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1];
- R1 = rotate_left(R1, 2);
+ R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1];
+ R1 = rotate_left(R1, 2);
- R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2];
- R2 = rotate_left(R2, 3);
+ R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2];
+ R2 = rotate_left(R2, 3);
- R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3];
- R3 = rotate_left(R3, 5);
+ R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3];
+ R3 = rotate_left(R3, 5);
- if(j == 4 || j == 10)
- {
- R0 += K[R3 % 64];
- R1 += K[R0 % 64];
- R2 += K[R1 % 64];
- R3 += K[R2 % 64];
+ if(j == 4 || j == 10)
+ {
+ R0 += K[R3 % 64];
+ R1 += K[R0 % 64];
+ R2 += K[R1 % 64];
+ R3 += K[R2 % 64];
+ }
}
- }
- store_le(out, R0, R1, R2, R3);
+ store_le(out, R0, R1, R2, R3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* RC2 Decryption
*/
-void RC2::dec(const byte in[], byte out[]) const
+void RC2::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit R0 = load_le<u16bit>(in, 0);
- u16bit R1 = load_le<u16bit>(in, 1);
- u16bit R2 = load_le<u16bit>(in, 2);
- u16bit R3 = load_le<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 16; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R3 = rotate_right(R3, 5);
- R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)];
+ u16bit R0 = load_le<u16bit>(in, 0);
+ u16bit R1 = load_le<u16bit>(in, 1);
+ u16bit R2 = load_le<u16bit>(in, 2);
+ u16bit R3 = load_le<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 16; ++j)
+ {
+ R3 = rotate_right(R3, 5);
+ R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)];
- R2 = rotate_right(R2, 3);
- R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)];
+ R2 = rotate_right(R2, 3);
+ R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)];
- R1 = rotate_right(R1, 2);
- R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)];
+ R1 = rotate_right(R1, 2);
+ R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)];
- R0 = rotate_right(R0, 1);
- R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)];
+ R0 = rotate_right(R0, 1);
+ R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)];
- if(j == 4 || j == 10)
- {
- R3 -= K[R2 % 64];
- R2 -= K[R1 % 64];
- R1 -= K[R0 % 64];
- R0 -= K[R3 % 64];
+ if(j == 4 || j == 10)
+ {
+ R3 -= K[R2 % 64];
+ R2 -= K[R1 % 64];
+ R1 -= K[R0 % 64];
+ R0 -= K[R3 % 64];
+ }
}
- }
- store_le(out, R0, R1, R2, R3);
+ store_le(out, R0, R1, R2, R3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*