summaryrefslogtreecommitdiff
path: root/chacha.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2018-10-25 12:08:32 -0400
committerJeffrey Walton <noloader@gmail.com>2018-10-25 12:08:32 -0400
commitb1050636a6148a937c61d19d100f4f808bde04aa (patch)
tree508d7f6b6fc9fcf15a3be87ad04a7b6251eb324a /chacha.cpp
parent352083b1d06f73ea571ff4804d4169630e3eab88 (diff)
downloadcryptopp-git-b1050636a6148a937c61d19d100f4f808bde04aa.tar.gz
Add ChaCha NEON implementation
Diffstat (limited to 'chacha.cpp')
-rw-r--r--chacha.cpp34
1 files changed, 33 insertions, 1 deletions
diff --git a/chacha.cpp b/chacha.cpp
index 23fd3be8..aa2e9268 100644
--- a/chacha.cpp
+++ b/chacha.cpp
@@ -11,6 +11,10 @@
NAMESPACE_BEGIN(CryptoPP)
+#if (CRYPTOPP_ARM_NEON_AVAILABLE)
+extern void ChaCha_OperateKeystream_NEON(const word32 *state, const byte* input, byte *output, unsigned int rounds, bool xorInput);
+#endif
+
#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE)
extern void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds, bool xorInput);
#endif
@@ -34,6 +38,10 @@ std::string ChaCha_Policy::AlgorithmProvider() const
if (HasSSE2())
return "SSE2";
#endif
+#if (CRYPTOPP_ARM_NEON_AVAILABLE)
+ if (HasNEON())
+ return "NEON";
+#endif
return "C++";
}
@@ -92,6 +100,11 @@ unsigned int ChaCha_Policy::GetOptimalBlockSize() const
return 4*BYTES_PER_ITERATION;
else
#endif
+#if (CRYPTOPP_ARM_NEON_AVAILABLE)
+ if (HasNEON())
+ return 4*BYTES_PER_ITERATION;
+ else
+#endif
return BYTES_PER_ITERATION;
}
@@ -113,7 +126,26 @@ void ChaCha_Policy::OperateKeystream(KeystreamOperation operation,
if (m_state[12] < 4)
m_state[13]++;
- input += !!xorInput*4*BYTES_PER_ITERATION;
+ input += (!!xorInput)*4*BYTES_PER_ITERATION;
+ output += 4*BYTES_PER_ITERATION;
+ iterationCount -= 4;
+ }
+ }
+#endif
+
+#if (CRYPTOPP_ARM_NEON_AVAILABLE)
+ if (HasNEON())
+ {
+ while (iterationCount >= 4)
+ {
+ bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
+ ChaCha_OperateKeystream_NEON(m_state, input, output, m_rounds, xorInput);
+
+ m_state[12] += 4;
+ if (m_state[12] < 4)
+ m_state[13]++;
+
+ input += (!!xorInput)*4*BYTES_PER_ITERATION;
output += 4*BYTES_PER_ITERATION;
iterationCount -= 4;
}