aboutsummaryrefslogtreecommitdiff
path: root/libbutl/sha256.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-07-22 14:16:10 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-07-22 14:16:10 +0200
commit9efe8d1ed5ee210ae644b7118f1d674a2de5f3e8 (patch)
tree65092c9a8f6c8b87e1bfdd533481398e40f2fd32 /libbutl/sha256.hxx
parent374db6aebec2a008538c7708305b9be01000c013 (diff)
Add fast-path SHA256 functions for integral types
Diffstat (limited to 'libbutl/sha256.hxx')
-rw-r--r--libbutl/sha256.hxx38
1 files changed, 36 insertions, 2 deletions
diff --git a/libbutl/sha256.hxx b/libbutl/sha256.hxx
index e81b87b..459b46c 100644
--- a/libbutl/sha256.hxx
+++ b/libbutl/sha256.hxx
@@ -6,9 +6,10 @@
#define LIBBUTL_SHA256_HXX
#include <string>
-#include <cstring> // strlen()
+#include <cstring> // strlen(), memcpy()
#include <cstdint>
-#include <cstddef> // size_t
+#include <cstddef> // size_t
+#include <type_traits> // enable_if, is_integral
#include <libbutl/export.hxx>
@@ -50,6 +51,39 @@ namespace butl
explicit
sha256 (const char* s): sha256 () {append (s);}
+ // Append an integral type with a fast path optimization (see
+ // SHA256_Update() for details).
+ //
+ void
+ append (char c)
+ {
+ std::uint32_t r ((ctx_.count >> 3) & 0x3f);
+
+ if (1 < 64 - r)
+ {
+ ctx_.buf[r] = static_cast<std::uint8_t> (c);
+ ctx_.count += 8;
+ }
+ else
+ append (&c, 1);
+ }
+
+ template <typename T>
+ typename std::enable_if<std::is_integral<T>::value>::type
+ append (T x)
+ {
+ const std::size_t len (sizeof (x));
+ std::uint32_t r ((ctx_.count >> 3) & 0x3f);
+
+ if (len < 64 - r)
+ {
+ std::memcpy (&ctx_.buf[r], &x, sizeof (x));
+ ctx_.count += len << 3;
+ }
+ else
+ append (&x, len);
+ }
+
// Extract result.
//
// It can be obtained as either a 32-byte binary digest or as a 64-