aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-08-10 19:46:22 -0400
committerJack Lloyd <[email protected]>2018-08-10 19:46:22 -0400
commita584ca8d3dd9a7c62dd83a2b772d4645306c0bd1 (patch)
treefad0a9ab89a01f1bc2ebd4eac8b7c28bc583a732 /src/lib
parente9699a70cb21ec837c28e9732dad6a81321a462d (diff)
Specialize CTR::seek for 4-byte counters
When used with AES-128 on Skylake (AES-NI), improves GCM performance by 10% on small messages and 5% on 1K messages.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/stream/ctr/ctr.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp
index 6a7d81729..3608eedf9 100644
--- a/src/lib/stream/ctr/ctr.cpp
+++ b/src/lib/stream/ctr/ctr.cpp
@@ -205,13 +205,27 @@ void CTR_BE::seek(uint64_t offset)
const size_t BS = m_block_size;
// Set m_counter blocks to IV, IV + 1, ... IV + n
- for(size_t i = 1; i != m_ctr_blocks; ++i)
+
+ if(m_ctr_size == 4 && BS >= 8)
+ {
+ const uint32_t low32 = load_be<uint32_t>(&m_counter[BS-4], 0);
+ for(size_t i = 1; i != m_ctr_blocks; ++i)
+ {
+ copy_mem(&m_counter[i*BS], &m_counter[0], BS);
+ uint32_t c = low32 + i;
+ store_be(c, &m_counter[(BS-4)+i*BS]);
+ }
+ }
+ else
{
- buffer_insert(m_counter, i*BS, &m_counter[(i-1)*BS], BS);
+ for(size_t i = 1; i != m_ctr_blocks; ++i)
+ {
+ buffer_insert(m_counter, i*BS, &m_counter[(i-1)*BS], BS);
- for(size_t j = 0; j != m_ctr_size; ++j)
- if(++m_counter[i*BS + (BS - 1 - j)])
- break;
+ for(size_t j = 0; j != m_ctr_size; ++j)
+ if(++m_counter[i*BS + (BS - 1 - j)])
+ break;
+ }
}
if(base_counter > 0)