summaryrefslogtreecommitdiff
path: root/chacha.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2018-11-18 12:42:04 -0500
committerJeffrey Walton <noloader@gmail.com>2018-11-18 12:42:04 -0500
commite28b2e0f02dfdbd4794202d5829e3bf4afe63826 (patch)
tree4696bf8c97792715746883c00aa172907a3e9182 /chacha.cpp
parent70473f0cabf91ac059fdc92e047f695c71e04f89 (diff)
downloadcryptopp-git-e28b2e0f02dfdbd4794202d5829e3bf4afe63826.tar.gz
Switch between POWER7 and POWER4 (GH #656)
This is kind of tricky. We automatically drop from POWER7 to POWER4 if 7 is notavailable. However, if POWER7 is available the runtime test checks for HasAltivec(), and not HasPower7(), if the drop does not occur. All of this goodness is happening on an old Apple G4 laptop with Gentoo. It is a "new toolchain on old hardware".
Diffstat (limited to 'chacha.cpp')
-rw-r--r--chacha.cpp27
1 files changed, 24 insertions, 3 deletions
diff --git a/chacha.cpp b/chacha.cpp
index a89fa016..05075b17 100644
--- a/chacha.cpp
+++ b/chacha.cpp
@@ -25,6 +25,8 @@ extern void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input,
#endif
#if (CRYPTOPP_ALTIVEC_AVAILABLE)
+// ChaCha_OperateKeystream_POWER7 may be compiled with either -mcpu=power7 or
+// -mcpu=power4. The makefile drops to POWER4 if POWER7 is not available.
extern void ChaCha_OperateKeystream_POWER7(const word32 *state, const byte* input, byte *output, unsigned int rounds);
#endif
@@ -85,8 +87,7 @@ std::string ChaCha_Policy::AlgorithmProvider() const
if (HasPower7())
return "Power7";
else
-#endif
-#if (CRYPTOPP_ALTIVEC_AVAILABLE)
+#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
if (HasAltivec())
return "Altivec";
else
@@ -250,11 +251,31 @@ void ChaCha_Policy::OperateKeystream(KeystreamOperation operation,
}
#endif
-#if (CRYPTOPP_ALTIVEC_AVAILABLE)
+#if (CRYPTOPP_POWER7_AVAILABLE)
+ if (HasPower7())
+ {
+ while (iterationCount >= 4 && MultiBlockSafe(4))
+ {
+ // ChaCha_OperateKeystream_POWER7 compiled with -mcpu=power7 and -DCRYPTOPP_POWER7_AVAILABLE
+ const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
+ ChaCha_OperateKeystream_POWER7(m_state, xorInput ? input : NULLPTR, output, m_rounds);
+
+ // MultiBlockSafe avoids overflow on the counter words
+ 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;
+ }
+ }
+#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
if (HasAltivec())
{
while (iterationCount >= 4 && MultiBlockSafe(4))
{
+ // ChaCha_OperateKeystream_POWER7 compiled with -mcpu=power4 and -DCRYPTOPP_ALTIVEC_AVAILABLE
const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
ChaCha_OperateKeystream_POWER7(m_state, xorInput ? input : NULLPTR, output, m_rounds);