summaryrefslogtreecommitdiff
path: root/cipher/chacha20.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2014-08-06 20:05:16 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2014-11-02 16:00:48 +0200
commitc584f44543883346d5a565581ff99a0afce9c5e1 (patch)
tree622f1578883dad739eaca3ea222ddc00a1222db7 /cipher/chacha20.c
parent669a83ba86c38b271d85ed4bf1cabc7cc8160583 (diff)
downloadlibgcrypt-c584f44543883346d5a565581ff99a0afce9c5e1.tar.gz
chacha20: add ARMv7/NEON implementation
* cipher/Makefile.am: Add 'chacha20-armv7-neon.S'. * cipher/chacha20-armv7-neon.S: New. * cipher/chacha20.c (USE_NEON): New. [USE_NEON] (_gcry_chacha20_armv7_neon_blocks): New. (chacha20_do_setkey) [USE_NEON]: Use Neon implementation if HWF_ARM_NEON flag set. (selftest): Self-test encrypting buffer byte by byte. * configure.ac [neonsupport=yes]: Add 'chacha20-armv7-neon.lo'. -- Add Andrew Moon's public domain ARMv7/NEON implementation of ChaCha20. Original source is available at: https://github.com/floodyberry/chacha-opt Benchmark on Cortex-A8 (--cpu-mhz 1008): Old: CHACHA20 | nanosecs/byte mebibytes/sec cycles/byte STREAM enc | 13.45 ns/B 70.92 MiB/s 13.56 c/B STREAM dec | 13.45 ns/B 70.90 MiB/s 13.56 c/B New: CHACHA20 | nanosecs/byte mebibytes/sec cycles/byte STREAM enc | 6.20 ns/B 153.9 MiB/s 6.25 c/B STREAM dec | 6.20 ns/B 153.9 MiB/s 6.25 c/B Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/chacha20.c')
-rw-r--r--cipher/chacha20.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/cipher/chacha20.c b/cipher/chacha20.c
index ebba2fcb..c1847aa5 100644
--- a/cipher/chacha20.c
+++ b/cipher/chacha20.c
@@ -67,6 +67,16 @@
# define USE_AVX2 1
#endif
+/* USE_NEON indicates whether to enable ARM NEON assembly code. */
+#undef USE_NEON
+#ifdef ENABLE_NEON_SUPPORT
+# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
+ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
+ && defined(HAVE_GCC_INLINE_ASM_NEON)
+# define USE_NEON 1
+# endif
+#endif /*ENABLE_NEON_SUPPORT*/
+
struct CHACHA20_context_s;
@@ -104,6 +114,13 @@ unsigned int _gcry_chacha20_amd64_avx2_blocks(u32 *state, const byte *in,
#endif /* USE_AVX2 */
+#ifdef USE_NEON
+
+unsigned int _gcry_chacha20_armv7_neon_blocks(u32 *state, const byte *in,
+ byte *out, size_t bytes);
+
+#endif /* USE_NEON */
+
static void chacha20_setiv (void *context, const byte * iv, size_t ivlen);
static const char *selftest (void);
@@ -353,6 +370,10 @@ chacha20_do_setkey (CHACHA20_context_t * ctx,
if (features & HWF_INTEL_AVX2)
ctx->blocks = _gcry_chacha20_amd64_avx2_blocks;
#endif
+#ifdef USE_NEON
+ if (features & HWF_ARM_NEON)
+ ctx->blocks = _gcry_chacha20_armv7_neon_blocks;
+#endif
(void)features;
@@ -541,6 +562,19 @@ selftest (void)
if (buf[i] != (byte) i)
return "ChaCha20 encryption test 2 failed.";
+ chacha20_setkey (&ctx, key_1, sizeof key_1);
+ chacha20_setiv (&ctx, nonce_1, sizeof nonce_1);
+ /* encrypt */
+ for (i = 0; i < sizeof buf; i++)
+ chacha20_encrypt_stream (&ctx, &buf[i], &buf[i], 1);
+ /* decrypt */
+ chacha20_setkey (&ctx, key_1, sizeof key_1);
+ chacha20_setiv (&ctx, nonce_1, sizeof nonce_1);
+ chacha20_encrypt_stream (&ctx, buf, buf, sizeof buf);
+ for (i = 0; i < sizeof buf; i++)
+ if (buf[i] != (byte) i)
+ return "ChaCha20 encryption test 3 failed.";
+
return NULL;
}