summaryrefslogtreecommitdiff
path: root/poly1305.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2019-01-26 13:53:21 -0500
committerJeffrey Walton <noloader@gmail.com>2019-01-26 13:53:21 -0500
commit6a76dc5ecfb734080ddad22bcd0fd054ff234b81 (patch)
treef903bd9bd196e5a3d3c6632e8c550fd2b024833c /poly1305.cpp
parente17f17d8fcca13874b37c261311d8556804c3c00 (diff)
downloadcryptopp-git-6a76dc5ecfb734080ddad22bcd0fd054ff234b81.tar.gz
Refactor Poly1305(AES) in preparation for IETF rendition (GH #727)
Diffstat (limited to 'poly1305.cpp')
-rw-r--r--poly1305.cpp275
1 files changed, 147 insertions, 128 deletions
diff --git a/poly1305.cpp b/poly1305.cpp
index 934d5935..8778a6f0 100644
--- a/poly1305.cpp
+++ b/poly1305.cpp
@@ -25,112 +25,29 @@
#include "aes.h"
#include "cpu.h"
-NAMESPACE_BEGIN(CryptoPP)
-
#define CONSTANT_TIME_CARRY(a,b) ((a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1))
-template <class T>
-std::string Poly1305_Base<T>::AlgorithmProvider() const
-{
- return m_cipher.AlgorithmProvider();
-}
-
-template <class T>
-void Poly1305_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
-{
- if (key && length)
- {
- // key is {k,r} pair, r is 16 bytes
- length = SaturatingSubtract(length, (unsigned)BLOCKSIZE);
- m_cipher.SetKey(key, length);
- key += length;
-
- // Rbar is clamped and little endian
- m_r[0] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, key + 0) & 0x0fffffff;
- m_r[1] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, key + 4) & 0x0ffffffc;
- m_r[2] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, key + 8) & 0x0ffffffc;
- m_r[3] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, key + 12) & 0x0ffffffc;
-
- m_used = false;
- }
-
- ConstByteArrayParameter t;
- if (params.GetValue(Name::IV(), t) && t.begin() && t.size())
- {
- // Nonce key is a class member to avoid the zeroizer on a temporary
- CRYPTOPP_ASSERT(t.size() == m_nk.size());
- std::memcpy(m_nk.begin(), t.begin(), m_nk.size());
- m_cipher.ProcessBlock(m_nk.begin());
-
- m_n[0] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 0);
- m_n[1] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 4);
- m_n[2] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 8);
- m_n[3] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 12);
-
- m_used = false;
- }
+ANONYMOUS_NAMESPACE_BEGIN
- Restart();
-}
+using namespace CryptoPP;
+enum {BLOCKSIZE=16};
-template <class T>
-void Poly1305_Base<T>::Update(const byte *input, size_t length)
-{
- CRYPTOPP_ASSERT((input && length) || !length);
- if (!length) return;
-
- size_t rem, num = m_idx;
- if (num)
- {
- rem = BLOCKSIZE - num;
- if (length >= rem)
- {
- // Process
- memcpy_s(m_acc + num, BLOCKSIZE - num, input, rem);
- HashBlocks(m_acc, BLOCKSIZE, 1);
- input += rem;
- length -= rem;
- }
- else
- {
- // Accumulate
- memcpy_s(m_acc + num, BLOCKSIZE - num, input, length);
- m_idx = num + length;
- return;
- }
- }
-
- rem = length % BLOCKSIZE;
- length -= rem;
-
- if (length >= BLOCKSIZE) {
- HashBlocks(input, length, 1);
- input += length;
- }
-
- if (rem)
- memcpy(m_acc, input, rem);
-
- m_idx = rem;
-}
-
-template <class T>
-void Poly1305_Base<T>::HashBlocks(const byte *input, size_t length, word32 padbit)
+void Poly1305_HashBlocks(word32 h[5], word32 r[4], const byte *input, size_t length, word32 padbit)
{
word32 r0, r1, r2, r3;
word32 s1, s2, s3;
word32 h0, h1, h2, h3, h4, c;
word64 d0, d1, d2, d3;
- r0 = m_r[0]; r1 = m_r[1];
- r2 = m_r[2]; r3 = m_r[3];
+ r0 = r[0]; r1 = r[1];
+ r2 = r[2]; r3 = r[3];
s1 = r1 + (r1 >> 2);
s2 = r2 + (r2 >> 2);
s3 = r3 + (r3 >> 2);
- h0 = m_h[0]; h1 = m_h[1]; h2 = m_h[2];
- h3 = m_h[3]; h4 = m_h[4];
+ h0 = h[0]; h1 = h[1]; h2 = h[2];
+ h3 = h[3]; h4 = h[4];
while (length >= BLOCKSIZE)
{
@@ -183,47 +100,22 @@ void Poly1305_Base<T>::HashBlocks(const byte *input, size_t length, word32 padbi
length -= BLOCKSIZE;
}
- m_h[0] = h0; m_h[1] = h1; m_h[2] = h2;
- m_h[3] = h3; m_h[4] = h4;
+ h[0] = h0; h[1] = h1; h[2] = h2;
+ h[3] = h3; h[4] = h4;
}
-template <class T>
-void Poly1305_Base<T>::TruncatedFinal(byte *mac, size_t size)
-{
- CRYPTOPP_ASSERT(mac); // Pointer is valid
- CRYPTOPP_ASSERT(!m_used); // Nonce is fresh
-
- ThrowIfInvalidTruncatedSize(size);
-
- size_t num = m_idx;
- if (num)
- {
- m_acc[num++] = 1; /* pad bit */
- while (num < BLOCKSIZE)
- m_acc[num++] = 0;
- HashBlocks(m_acc, BLOCKSIZE, 0);
- }
-
- HashFinal(mac, size);
-
- // Restart
- m_used = true;
- Restart();
-}
-
-template <class T>
-void Poly1305_Base<T>::HashFinal(byte *mac, size_t size)
+void Poly1305_HashFinal(word32 h[5], word32 n[4], byte *mac, size_t size)
{
word32 h0, h1, h2, h3, h4;
word32 g0, g1, g2, g3, g4;
word32 mask;
word64 t;
- h0 = m_h[0];
- h1 = m_h[1];
- h2 = m_h[2];
- h3 = m_h[3];
- h4 = m_h[4];
+ h0 = h[0];
+ h1 = h[1];
+ h2 = h[2];
+ h3 = h[3];
+ h4 = h[4];
// compare to modulus by computing h + -p
g0 = (word32)(t = (word64)h0 + 5);
@@ -241,10 +133,10 @@ void Poly1305_Base<T>::HashFinal(byte *mac, size_t size)
h2 = (h2 & mask) | g2; h3 = (h3 & mask) | g3;
// mac = (h + nonce) % (2^128)
- h0 = (word32)(t = (word64)h0 + m_n[0]);
- h1 = (word32)(t = (word64)h1 + (t >> 32) + m_n[1]);
- h2 = (word32)(t = (word64)h2 + (t >> 32) + m_n[2]);
- h3 = (word32)(t = (word64)h3 + (t >> 32) + m_n[3]);
+ h0 = (word32)(t = (word64)h0 + n[0]);
+ h1 = (word32)(t = (word64)h1 + (t >> 32) + n[1]);
+ h2 = (word32)(t = (word64)h2 + (t >> 32) + n[2]);
+ h3 = (word32)(t = (word64)h3 + (t >> 32) + n[3]);
if (size >= BLOCKSIZE)
{
@@ -264,6 +156,133 @@ void Poly1305_Base<T>::HashFinal(byte *mac, size_t size)
}
}
+ANONYMOUS_NAMESPACE_END
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// No longer needed. Remove at next major version bump
+template <class T>
+void Poly1305_Base<T>::HashBlocks(const byte *input, size_t length, word32 padbit) {
+ CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(padbit);
+ CRYPTOPP_ASSERT(0);
+}
+
+// No longer needed. Remove at next major version bump
+template <class T>
+void Poly1305_Base<T>::HashFinal(byte *mac, size_t length) {
+ CRYPTOPP_UNUSED(mac); CRYPTOPP_UNUSED(length);
+ CRYPTOPP_ASSERT(0);
+}
+
+template <class T>
+std::string Poly1305_Base<T>::AlgorithmProvider() const
+{
+ return m_cipher.AlgorithmProvider();
+}
+
+template <class T>
+void Poly1305_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
+{
+ if (key && length)
+ {
+ // key is {k,r} pair, r is 16 bytes
+ length = SaturatingSubtract(length, (unsigned)BLOCKSIZE);
+ m_cipher.SetKey(key, length);
+ key += length;
+
+ // Rbar is clamped and little endian
+ m_r[0] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, key + 0) & 0x0fffffff;
+ m_r[1] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, key + 4) & 0x0ffffffc;
+ m_r[2] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, key + 8) & 0x0ffffffc;
+ m_r[3] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, key + 12) & 0x0ffffffc;
+
+ m_used = false;
+ }
+
+ ConstByteArrayParameter t;
+ if (params.GetValue(Name::IV(), t) && t.begin() && t.size())
+ {
+ // Nonce key is a class member to avoid the zeroizer on a temporary
+ CRYPTOPP_ASSERT(t.size() == m_nk.size());
+ std::memcpy(m_nk.begin(), t.begin(), m_nk.size());
+ m_cipher.ProcessBlock(m_nk.begin());
+
+ m_n[0] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 0);
+ m_n[1] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 4);
+ m_n[2] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 8);
+ m_n[3] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 12);
+
+ m_used = false;
+ }
+
+ Restart();
+}
+
+template <class T>
+void Poly1305_Base<T>::Update(const byte *input, size_t length)
+{
+ CRYPTOPP_ASSERT((input && length) || !length);
+ if (!length) return;
+
+ size_t rem, num = m_idx;
+ if (num)
+ {
+ rem = BLOCKSIZE - num;
+ if (length >= rem)
+ {
+ // Process
+ memcpy_s(m_acc + num, BLOCKSIZE - num, input, rem);
+ Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 1);
+ input += rem;
+ length -= rem;
+ }
+ else
+ {
+ // Accumulate
+ memcpy_s(m_acc + num, BLOCKSIZE - num, input, length);
+ m_idx = num + length;
+ return;
+ }
+ }
+
+ rem = length % BLOCKSIZE;
+ length -= rem;
+
+ if (length >= BLOCKSIZE) {
+ Poly1305_HashBlocks(m_h, m_r, input, length, 1);
+ input += length;
+ }
+
+ if (rem)
+ memcpy(m_acc, input, rem);
+
+ m_idx = rem;
+}
+
+template <class T>
+void Poly1305_Base<T>::TruncatedFinal(byte *mac, size_t size)
+{
+ CRYPTOPP_ASSERT(mac); // Pointer is valid
+ CRYPTOPP_ASSERT(!m_used); // Nonce is fresh
+
+ ThrowIfInvalidTruncatedSize(size);
+
+ size_t num = m_idx;
+ if (num)
+ {
+ m_acc[num++] = 1; /* pad bit */
+ while (num < BLOCKSIZE)
+ m_acc[num++] = 0;
+ Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 0);
+ }
+
+ Poly1305_HashFinal(m_h, m_n, mac, size);
+
+ // Restart
+ m_used = true;
+ Restart();
+}
+
template <class T>
void Poly1305_Base<T>::Resynchronize(const byte *nonce, int nonceLength)
{