Speedup Hash_DRBG and HMAC_DRBG
Add benchmarks for SHA1 and SHA256 variants Hash_DRBG sped-up by about 2 MiB/s by using word128 and word64 in the initial update loop. It did not benefit other loops HMAC_DRBG sped-up by about 5 MiB/s by reworking variables, access and loop controlpull/354/merge
parent
006ca5f860
commit
ef7a6a2f4e
|
|
@ -407,7 +407,9 @@ void Benchmark1(double t, double hertz)
|
||||||
BenchMarkByNameKeyLess<RandomNumberGenerator>("RDSEED");
|
BenchMarkByNameKeyLess<RandomNumberGenerator>("RDSEED");
|
||||||
#endif
|
#endif
|
||||||
BenchMarkByNameKeyLess<NIST_DRBG>("Hash_DRBG(SHA1)");
|
BenchMarkByNameKeyLess<NIST_DRBG>("Hash_DRBG(SHA1)");
|
||||||
|
BenchMarkByNameKeyLess<NIST_DRBG>("Hash_DRBG(SHA256)");
|
||||||
BenchMarkByNameKeyLess<NIST_DRBG>("HMAC_DRBG(SHA1)");
|
BenchMarkByNameKeyLess<NIST_DRBG>("HMAC_DRBG(SHA1)");
|
||||||
|
BenchMarkByNameKeyLess<NIST_DRBG>("HMAC_DRBG(SHA256)");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "\n<TBODY style=\"background: yellow;\">";
|
std::cout << "\n<TBODY style=\"background: yellow;\">";
|
||||||
|
|
|
||||||
46
drbg.h
46
drbg.h
|
|
@ -458,18 +458,18 @@ void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Generate(const byte* additional
|
||||||
hash.Final(w);
|
hash.Final(w);
|
||||||
|
|
||||||
CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
|
CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
|
||||||
int carry=0, i=SEEDLENGTH-1, j=HASH::DIGESTSIZE-1;
|
int carry=0, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
|
||||||
while(i>=0 && j>=0)
|
while (j>=0)
|
||||||
{
|
{
|
||||||
carry = m_v[i] + w[j] + carry;
|
carry = m_v[i] + w[j] + carry;
|
||||||
m_v[i] = static_cast<byte>(carry);
|
m_v[i] = static_cast<byte>(carry);
|
||||||
carry >>= 8; i--; j--;
|
j--; i--; carry >>= 8;
|
||||||
}
|
}
|
||||||
while (carry && i>=0)
|
while (i>=0)
|
||||||
{
|
{
|
||||||
carry = m_v[i] + carry;
|
carry = m_v[i] + carry;
|
||||||
m_v[i] = static_cast<byte>(carry);
|
m_v[i] = static_cast<byte>(carry);
|
||||||
carry >>= 8; i--;
|
i--; carry >>= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -485,7 +485,7 @@ void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Generate(const byte* additional
|
||||||
hash.TruncatedFinal(output, count);
|
hash.TruncatedFinal(output, count);
|
||||||
|
|
||||||
IncrementCounterByOne(data, static_cast<unsigned int>(data.size()));
|
IncrementCounterByOne(data, static_cast<unsigned int>(data.size()));
|
||||||
output += count; size -= count;
|
size -= count; output += count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -501,25 +501,47 @@ void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Generate(const byte* additional
|
||||||
|
|
||||||
CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
|
CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
|
||||||
CRYPTOPP_ASSERT(HASH::DIGESTSIZE >= sizeof(m_reseed));
|
CRYPTOPP_ASSERT(HASH::DIGESTSIZE >= sizeof(m_reseed));
|
||||||
int carry=0, i=SEEDLENGTH-1, j=HASH::DIGESTSIZE-1, k=sizeof(m_reseed)-1;
|
int carry=0, k=sizeof(m_reseed)-1, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
|
||||||
while(i>=0 && j>=0 && k>=0)
|
|
||||||
|
// Using Integer class slows things down by about 8 cpb.
|
||||||
|
// Using word128 and word64 benefits the first loop only by about 2 cpb.
|
||||||
|
#if defined(CRYPTOPP_WORD128_AVAILABLE)
|
||||||
|
byte* p1 = m_v.begin()+SEEDLENGTH-8;
|
||||||
|
byte* p2 = m_c.begin()+SEEDLENGTH-8;
|
||||||
|
byte* p3 = h.begin()+HASH::DIGESTSIZE-8;
|
||||||
|
|
||||||
|
word64 w1 = GetWord<word64>(false, BIG_ENDIAN_ORDER, p1);
|
||||||
|
word64 w2 = GetWord<word64>(false, BIG_ENDIAN_ORDER, p2);
|
||||||
|
word64 w3 = GetWord<word64>(false, BIG_ENDIAN_ORDER, p3);
|
||||||
|
word64 w4 = m_reseed;
|
||||||
|
|
||||||
|
word128 r = static_cast<word128>(w1) + w2 + w3 + w4;
|
||||||
|
PutWord(false, BIG_ENDIAN_ORDER, p1, static_cast<word64>(r));
|
||||||
|
j -= 8; i -= 8; k=0; carry = static_cast<int>(r >> 64);
|
||||||
|
#else
|
||||||
|
while (k>=0)
|
||||||
{
|
{
|
||||||
carry = m_v[i] + m_c[i] + h[j] + GetByte<word64>(BIG_ENDIAN_ORDER, m_reseed, k) + carry;
|
carry = m_v[i] + m_c[i] + h[j] + GetByte<word64>(BIG_ENDIAN_ORDER, m_reseed, k) + carry;
|
||||||
m_v[i] = static_cast<byte>(carry);
|
m_v[i] = static_cast<byte>(carry);
|
||||||
carry >>= 8; i--; j--; k--;
|
k--; j--; i--; carry >>= 8;
|
||||||
}
|
}
|
||||||
while(i>=0 && j>=0)
|
#endif
|
||||||
|
|
||||||
|
while (j>=0)
|
||||||
{
|
{
|
||||||
carry = m_v[i] + m_c[i] + h[j] + carry;
|
carry = m_v[i] + m_c[i] + h[j] + carry;
|
||||||
m_v[i] = static_cast<byte>(carry);
|
m_v[i] = static_cast<byte>(carry);
|
||||||
carry >>= 8; i--; j--;
|
j--; i--; carry >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i>=0)
|
while (i>=0)
|
||||||
{
|
{
|
||||||
carry = m_v[i] + m_c[i] + carry;
|
carry = m_v[i] + m_c[i] + carry;
|
||||||
m_v[i] = static_cast<byte>(carry);
|
m_v[i] = static_cast<byte>(carry);
|
||||||
carry >>= 8; i--;
|
i--;
|
||||||
|
carry >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_reseed++;
|
m_reseed++;
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,9 @@ void RegisterFactories()
|
||||||
RegisterDefaultFactoryFor<RandomNumberGenerator, RDSEED>();
|
RegisterDefaultFactoryFor<RandomNumberGenerator, RDSEED>();
|
||||||
#endif
|
#endif
|
||||||
RegisterDefaultFactoryFor<NIST_DRBG, Hash_DRBG<SHA1> >("Hash_DRBG(SHA1)");
|
RegisterDefaultFactoryFor<NIST_DRBG, Hash_DRBG<SHA1> >("Hash_DRBG(SHA1)");
|
||||||
|
RegisterDefaultFactoryFor<NIST_DRBG, Hash_DRBG<SHA256> >("Hash_DRBG(SHA256)");
|
||||||
RegisterDefaultFactoryFor<NIST_DRBG, HMAC_DRBG<SHA1> >("HMAC_DRBG(SHA1)");
|
RegisterDefaultFactoryFor<NIST_DRBG, HMAC_DRBG<SHA1> >("HMAC_DRBG(SHA1)");
|
||||||
|
RegisterDefaultFactoryFor<NIST_DRBG, HMAC_DRBG<SHA256> >("HMAC_DRBG(SHA256)");
|
||||||
|
|
||||||
s_registered = true;
|
s_registered = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue