diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2012-11-29 21:54:57 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2012-12-03 14:23:30 +0100 |
commit | 162791bc08f4fc9b3882671e68ecdfd9e130ae59 (patch) | |
tree | a8049486305ee64ae588ee7d87a4d4ff12c07ef4 /cipher/cipher-ctr.c | |
parent | 9ee9e25f519696d509b1a5c1cc04ab0121e98a51 (diff) | |
download | libgcrypt-162791bc08f4fc9b3882671e68ecdfd9e130ae59.tar.gz |
Optimize buffer xoring.
* cipher/Makefile.am (libcipher_la_SOURCES): Add 'bufhelp.h'.
* cipher/bufhelp.h: New.
* cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt)
(_gcry_cipher_aeswrap_decrypt): Use 'buf_xor' for buffer xoring.
* cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
(_gcry_cipher_cbc_decrypt): Use 'buf_xor' for buffer xoring and remove
resulting unused variables.
* cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt) Use 'buf_xor_2dst'
for buffer xoring and remove resulting unused variables.
(_gcry_cipher_cfb_decrypt): Use 'buf_xor_n_copy' for buffer xoring and
remove resulting unused variables.
* cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Use 'buf_xor' for
buffer xoring and remove resulting unused variables.
* cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt)
(_gcry_cipher_ofb_decrypt): Use 'buf_xor' for buffer xoring and remove
resulting used variables.
* cipher/rijndael.c (_gry_aes_cfb_enc): Use 'buf_xor_2dst' for buffer
xoring and remove resulting unused variables.
(_gry_aes_cfb_dev): Use 'buf_xor_n_copy' for buffer xoring and remove
resulting unused variables.
(_gry_aes_cbc_enc, _gry_aes_ctr_enc, _gry_aes_cbc_dec): Use 'buf_xor'
for buffer xoring and remove resulting unused variables.
--
Add faster helper functions for buffer xoring and replace byte buffer xor
loops. This give following speed up. Note that CTR speed up is from refactoring
code to use buf_xor() and removal of integer division/modulo operations issued
per each processed byte. This removal of div/mod most likely gives even greater
speed increase on CPU architechtures that do not have hardware division unit.
Benchmark ratios (old-vs-new, AMD Phenom II, x86-64):
ECB/Stream CBC CFB OFB CTR
--------------- --------------- --------------- --------------- ---------------
IDEA 0.99x 1.01x 1.06x 1.02x 1.03x 1.06x 1.04x 1.02x 1.58x 1.58x
3DES 1.00x 1.00x 1.01x 1.01x 1.02x 1.02x 1.02x 1.01x 1.22x 1.23x
CAST5 0.98x 1.00x 1.09x 1.03x 1.09x 1.09x 1.07x 1.07x 1.98x 1.95x
BLOWFISH 1.00x 1.00x 1.18x 1.05x 1.07x 1.07x 1.05x 1.05x 1.93x 1.91x
AES 1.00x 0.98x 1.18x 1.14x 1.13x 1.13x 1.14x 1.14x 1.18x 1.18x
AES192 0.98x 1.00x 1.13x 1.14x 1.13x 1.10x 1.14x 1.16x 1.15x 1.15x
AES256 0.97x 1.02x 1.09x 1.13x 1.13x 1.09x 1.10x 1.14x 1.11x 1.13x
TWOFISH 1.00x 1.00x 1.15x 1.17x 1.18x 1.16x 1.18x 1.13x 2.37x 2.31x
ARCFOUR 1.03x 0.97x
DES 1.01x 1.00x 1.04x 1.04x 1.04x 1.05x 1.05x 1.02x 1.56x 1.55x
TWOFISH128 0.97x 1.03x 1.18x 1.17x 1.18x 1.15x 1.15x 1.15x 2.37x 2.31x
SERPENT128 1.00x 1.00x 1.10x 1.11x 1.08x 1.09x 1.08x 1.06x 1.66x 1.67x
SERPENT192 1.00x 1.00x 1.07x 1.08x 1.08x 1.09x 1.08x 1.08x 1.65x 1.66x
SERPENT256 1.00x 1.00x 1.09x 1.09x 1.08x 1.09x 1.08x 1.06x 1.66x 1.67x
RFC2268_40 1.03x 0.99x 1.05x 1.02x 1.03x 1.03x 1.04x 1.03x 1.46x 1.46x
SEED 1.00x 1.00x 1.10x 1.10x 1.09x 1.09x 1.10x 1.07x 1.80x 1.76x
CAMELLIA128 1.00x 1.00x 1.23x 1.12x 1.15x 1.17x 1.15x 1.12x 2.15x 2.13x
CAMELLIA192 1.05x 1.03x 1.23x 1.21x 1.21x 1.16x 1.12x 1.25x 1.90x 1.90x
CAMELLIA256 1.03x 1.07x 1.10x 1.19x 1.08x 1.14x 1.12x 1.10x 1.90x 1.92x
Benchmark ratios (old-vs-new, AMD Phenom II, i386):
ECB/Stream CBC CFB OFB CTR
--------------- --------------- --------------- --------------- ---------------
IDEA 1.00x 1.00x 1.04x 1.05x 1.04x 1.02x 1.02x 1.02x 1.38x 1.40x
3DES 1.01x 1.00x 1.02x 1.04x 1.03x 1.01x 1.00x 1.02x 1.20x 1.20x
CAST5 1.00x 1.00x 1.03x 1.09x 1.07x 1.04x 1.13x 1.00x 1.74x 1.74x
BLOWFISH 1.04x 1.08x 1.03x 1.13x 1.07x 1.12x 1.03x 1.00x 1.78x 1.74x
AES 0.96x 1.00x 1.09x 1.08x 1.14x 1.13x 1.07x 1.03x 1.14x 1.09x
AES192 1.00x 1.03x 1.07x 1.03x 1.07x 1.07x 1.06x 1.03x 1.08x 1.11x
AES256 1.00x 1.00x 1.06x 1.06x 1.10x 1.06x 1.05x 1.03x 1.10x 1.10x
TWOFISH 0.95x 1.10x 1.13x 1.23x 1.05x 1.14x 1.09x 1.13x 1.95x 1.86x
ARCFOUR 1.00x 1.00x
DES 1.02x 0.98x 1.04x 1.04x 1.05x 1.02x 1.04x 1.00x 1.45x 1.48x
TWOFISH128 0.95x 1.10x 1.26x 1.19x 1.09x 1.14x 1.17x 1.00x 2.00x 1.91x
SERPENT128 1.02x 1.00x 1.08x 1.04x 1.10x 1.06x 1.08x 1.04x 1.42x 1.42x
SERPENT192 1.02x 1.02x 1.06x 1.06x 1.10x 1.08x 1.04x 1.06x 1.42x 1.42x
SERPENT256 1.02x 0.98x 1.06x 1.06x 1.10x 1.06x 1.04x 1.06x 1.42x 1.40x
RFC2268_40 1.00x 1.00x 1.02x 1.06x 1.04x 1.02x 1.02x 1.02x 1.35x 1.35x
SEED 1.00x 0.97x 1.11x 1.05x 1.06x 1.08x 1.08x 1.05x 1.56x 1.57x
CAMELLIA128 1.03x 0.97x 1.12x 1.14x 1.06x 1.10x 1.06x 1.06x 1.73x 1.59x
CAMELLIA192 1.06x 1.00x 1.13x 1.10x 1.11x 1.11x 1.15x 1.08x 1.57x 1.58x
CAMELLIA256 1.06x 1.03x 1.10x 1.10x 1.11x 1.11x 1.13x 1.08x 1.57x 1.62x
[v2]:
- include stdint.h only when it's available
- use uintptr_t instead of long and intptr_t
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Diffstat (limited to 'cipher/cipher-ctr.c')
-rw-r--r-- | cipher/cipher-ctr.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/cipher/cipher-ctr.c b/cipher/cipher-ctr.c index a334abc5..6bc6ffc1 100644 --- a/cipher/cipher-ctr.c +++ b/cipher/cipher-ctr.c @@ -27,6 +27,7 @@ #include "g10lib.h" #include "cipher.h" #include "ath.h" +#include "bufhelp.h" #include "./cipher-internal.h" @@ -48,11 +49,9 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, { gcry_assert (c->unused < blocksize); i = blocksize - c->unused; - for (n=0; c->unused && n < inbuflen; c->unused--, n++, i++) - { - /* XOR input with encrypted counter and store in output. */ - outbuf[n] = inbuf[n] ^ c->lastiv[i]; - } + n = c->unused > inbuflen ? inbuflen : c->unused; + buf_xor(outbuf, inbuf, &c->lastiv[i], n); + c->unused -= n; inbuf += n; outbuf += n; inbuflen -= n; @@ -75,27 +74,26 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, { unsigned char tmp[MAX_BLOCKSIZE]; - for (n=0; n < inbuflen; n++) - { - if ((n % blocksize) == 0) - { - c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr); + do { + c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr); - for (i = blocksize; i > 0; i--) - { - c->u_ctr.ctr[i-1]++; - if (c->u_ctr.ctr[i-1] != 0) - break; - } - } + for (i = blocksize; i > 0; i--) + { + c->u_ctr.ctr[i-1]++; + if (c->u_ctr.ctr[i-1] != 0) + break; + } - /* XOR input with encrypted counter and store in output. */ - outbuf[n] = inbuf[n] ^ tmp[n % blocksize]; - } + n = blocksize < inbuflen ? blocksize : inbuflen; + buf_xor(outbuf, inbuf, tmp, n); + + inbuflen -= n; + outbuf += n; + inbuf += n; + } while (inbuflen); /* Save the unused bytes of the counter. */ - n %= blocksize; - c->unused = (blocksize - n) % blocksize; + c->unused = blocksize - n; if (c->unused) memcpy (c->lastiv+n, tmp+n, c->unused); |